blob: 5604dbd1cc7290bbff8f09faed56498abae1ce95 [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"
Yunchao Hea336b902017-08-02 16:05:21 +080029#include "libANGLE/ProgramPipeline.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050031#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050032#include "libANGLE/ResourceManager.h"
33#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050034#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050035#include "libANGLE/Texture.h"
36#include "libANGLE/TransformFeedback.h"
37#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070038#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040039#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030040#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040041#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040042#include "libANGLE/renderer/ContextImpl.h"
43#include "libANGLE/renderer/EGLImplFactory.h"
Jamie Madill7b62cf92017-11-02 15:20:49 -040044#include "libANGLE/renderer/Format.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040045#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000046
Geoff Langf6db0982015-08-25 13:04:00 -040047namespace
48{
49
Jamie Madillb6664922017-07-25 12:55:04 -040050#define ANGLE_HANDLE_ERR(X) \
51 handleError(X); \
52 return;
53#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR);
54
Ian Ewell3ffd78b2016-01-22 16:09:42 -050055template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050056std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030057 GLsizei numPaths,
58 const void *paths,
59 GLuint pathBase)
60{
61 std::vector<gl::Path *> ret;
62 ret.reserve(numPaths);
63
64 const auto *nameArray = static_cast<const T *>(paths);
65
66 for (GLsizei i = 0; i < numPaths; ++i)
67 {
68 const GLuint pathName = nameArray[i] + pathBase;
69
70 ret.push_back(resourceManager.getPath(pathName));
71 }
72
73 return ret;
74}
75
Geoff Lang4ddf5af2016-12-01 14:30:44 -050076std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030077 GLsizei numPaths,
78 GLenum pathNameType,
79 const void *paths,
80 GLuint pathBase)
81{
82 switch (pathNameType)
83 {
84 case GL_UNSIGNED_BYTE:
85 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
86
87 case GL_BYTE:
88 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
89
90 case GL_UNSIGNED_SHORT:
91 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
92
93 case GL_SHORT:
94 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
95
96 case GL_UNSIGNED_INT:
97 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
98
99 case GL_INT:
100 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
101 }
102
103 UNREACHABLE();
104 return std::vector<gl::Path *>();
105}
106
107template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400108gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109{
Geoff Lang2186c382016-10-14 10:54:54 -0400110 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500111
112 switch (pname)
113 {
114 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400115 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500116 case GL_QUERY_RESULT_AVAILABLE_EXT:
117 {
118 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400119 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500120 if (!error.isError())
121 {
jchen10a99ed552017-09-22 08:10:32 +0800122 *params = gl::CastFromStateValue<T>(pname, static_cast<GLuint>(available));
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500123 }
124 return error;
125 }
126 default:
127 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500128 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500129 }
130}
131
Geoff Langf6db0982015-08-25 13:04:00 -0400132void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
133{
Geoff Lang1a683462015-09-29 15:09:59 -0400134 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400135 {
136 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
137 tfBufferIndex++)
138 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400139 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400140 transformFeedback->getIndexedBuffer(tfBufferIndex);
141 if (buffer.get() != nullptr)
142 {
143 buffer->onTransformFeedback();
144 }
145 }
146 }
147}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500148
149// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300150EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400152 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500153}
154
Martin Radev1be913c2016-07-11 17:59:16 +0300155EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
156{
157 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
158}
159
Geoff Langeb66a6e2016-10-31 13:06:12 -0400160gl::Version GetClientVersion(const egl::AttributeMap &attribs)
161{
162 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
163}
164
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500165GLenum GetResetStrategy(const egl::AttributeMap &attribs)
166{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400167 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
Jeff Gilbertc5de4d22017-10-31 15:07:53 -0700168 EGL_NO_RESET_NOTIFICATION);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500169 switch (attrib)
170 {
171 case EGL_NO_RESET_NOTIFICATION:
172 return GL_NO_RESET_NOTIFICATION_EXT;
173 case EGL_LOSE_CONTEXT_ON_RESET:
174 return GL_LOSE_CONTEXT_ON_RESET_EXT;
175 default:
176 UNREACHABLE();
177 return GL_NONE;
178 }
179}
180
181bool GetRobustAccess(const egl::AttributeMap &attribs)
182{
Geoff Lang077f20a2016-11-01 10:08:02 -0400183 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
184 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
185 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500186}
187
188bool GetDebug(const egl::AttributeMap &attribs)
189{
Geoff Lang077f20a2016-11-01 10:08:02 -0400190 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
191 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500192}
193
194bool GetNoError(const egl::AttributeMap &attribs)
195{
196 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
197}
198
Geoff Langc287ea62016-09-16 14:46:51 -0400199bool GetWebGLContext(const egl::AttributeMap &attribs)
200{
201 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
202}
203
Geoff Langf41a7152016-09-19 15:11:17 -0400204bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
205{
206 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
207}
208
Geoff Langfeb8c682017-02-13 16:07:35 -0500209bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
210{
211 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
212}
213
Geoff Langb433e872017-10-05 14:01:47 -0400214bool GetRobustResourceInit(const egl::AttributeMap &attribs)
215{
216 return (attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
217}
218
Martin Radev9d901792016-07-15 15:58:58 +0300219std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
220{
221 std::string labelName;
222 if (label != nullptr)
223 {
224 size_t labelLength = length < 0 ? strlen(label) : length;
225 labelName = std::string(label, labelLength);
226 }
227 return labelName;
228}
229
230void GetObjectLabelBase(const std::string &objectLabel,
231 GLsizei bufSize,
232 GLsizei *length,
233 GLchar *label)
234{
235 size_t writeLength = objectLabel.length();
236 if (label != nullptr && bufSize > 0)
237 {
238 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
239 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
240 label[writeLength] = '\0';
241 }
242
243 if (length != nullptr)
244 {
245 *length = static_cast<GLsizei>(writeLength);
246 }
247}
248
Jamie Madill0f80ed82017-09-19 00:24:56 -0400249template <typename CapT, typename MaxT>
250void LimitCap(CapT *cap, MaxT maximum)
251{
252 *cap = std::min(*cap, static_cast<CapT>(maximum));
253}
254
Geoff Langf6db0982015-08-25 13:04:00 -0400255} // anonymous namespace
256
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000257namespace gl
258{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000259
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400260Context::Context(rx::EGLImplFactory *implFactory,
261 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400262 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500263 TextureManager *shareTextures,
Jamie Madill32447362017-06-28 14:53:52 -0400264 MemoryProgramCache *memoryProgramCache,
Corentin Wallezc295e512017-01-27 17:47:50 -0500265 const egl::AttributeMap &attribs,
Geoff Langb433e872017-10-05 14:01:47 -0400266 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300267
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500268 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500269 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500270 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700271 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500272 mCaps,
273 mTextureCaps,
274 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500275 mLimitations,
276 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700277 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400278 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400279 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500280 mClientType(EGL_OPENGL_ES_API),
281 mHasBeenCurrent(false),
282 mContextLost(false),
283 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700284 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500285 mResetStrategy(GetResetStrategy(attribs)),
286 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400287 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
288 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500289 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500290 mWebGLContext(GetWebGLContext(attribs)),
Jamie Madill32447362017-06-28 14:53:52 -0400291 mMemoryProgramCache(memoryProgramCache),
Jamie Madillb3f26b92017-07-19 15:07:41 -0400292 mScratchBuffer(1000u),
293 mZeroFilledBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000294{
Jamie Madill14bbb3f2017-09-12 15:23:01 -0400295 mImplementation->setMemoryProgramCache(memoryProgramCache);
296
Geoff Langb433e872017-10-05 14:01:47 -0400297 bool robustResourceInit = GetRobustResourceInit(attribs);
298 initCaps(displayExtensions, robustResourceInit);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700299 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400300
Jamie Madill4928b7c2017-06-20 12:57:39 -0400301 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400302 GetClientArraysEnabled(attribs), robustResourceInit,
303 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100304
Shannon Woods53a94a82014-06-24 15:20:36 -0400305 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400306
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000307 // [OpenGL ES 2.0.24] section 3.7 page 83:
Corentin Wallez336129f2017-10-17 15:55:40 -0400308 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have two-dimensional
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000309 // and cube map texture state vectors respectively associated with them.
310 // In order that access to these initial textures not be lost, they are treated as texture
311 // objects all of whose names are 0.
312
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400313 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400314 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500315
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400316 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400317 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400318
Geoff Langeb66a6e2016-10-31 13:06:12 -0400319 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400320 {
321 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400322 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400323 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400324
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400325 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400326 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400327 }
Geoff Lang3b573612016-10-31 14:08:10 -0400328 if (getClientVersion() >= Version(3, 1))
329 {
330 Texture *zeroTexture2DMultisample =
331 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400332 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800333
Jiajia Qin6eafb042016-12-27 17:04:07 +0800334 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
335 {
Corentin Wallez336129f2017-10-17 15:55:40 -0400336 bindBufferRange(BufferBinding::AtomicCounter, 0, i, 0, 0);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800337 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800338
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800339 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
340 {
Corentin Wallez336129f2017-10-17 15:55:40 -0400341 bindBufferRange(BufferBinding::ShaderStorage, i, 0, 0, 0);
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800342 }
Geoff Lang3b573612016-10-31 14:08:10 -0400343 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000344
Geoff Lang4751aab2017-10-30 15:14:52 -0400345 const Extensions &nativeExtensions = mImplementation->getNativeExtensions();
346 if (nativeExtensions.textureRectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400347 {
348 Texture *zeroTextureRectangle =
349 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
350 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
351 }
352
Geoff Lang4751aab2017-10-30 15:14:52 -0400353 if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal)
Ian Ewellbda75592016-04-18 17:25:54 -0400354 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400355 Texture *zeroTextureExternal =
356 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400357 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400358 }
359
Jamie Madill4928b7c2017-06-20 12:57:39 -0400360 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500361
Jamie Madill57a89722013-07-02 11:57:03 -0400362 bindVertexArray(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000363
Geoff Langeb66a6e2016-10-31 13:06:12 -0400364 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400365 {
366 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
367 // In the initial state, a default transform feedback object is bound and treated as
368 // a transform feedback object with a name of zero. That object is bound any time
369 // BindTransformFeedback is called with id of zero
Jamie Madillf0dcb8b2017-08-26 19:05:13 -0400370 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Geoff Lang1a683462015-09-29 15:09:59 -0400371 }
Geoff Langc8058452014-02-03 12:04:11 -0500372
Corentin Wallez336129f2017-10-17 15:55:40 -0400373 for (auto type : angle::AllEnums<BufferBinding>())
374 {
375 bindBuffer(type, 0);
376 }
377
378 bindRenderbuffer(GL_RENDERBUFFER, 0);
379
380 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
381 {
382 bindBufferRange(BufferBinding::Uniform, i, 0, 0, -1);
383 }
384
Jamie Madillad9f24e2016-02-12 09:27:24 -0500385 // Initialize dirty bit masks
Jamie Madillc67323a2017-11-02 23:11:41 -0400386 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE);
Corentin Wallez29a20992017-11-06 18:23:16 -0500387 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500388 // No dirty objects.
389
390 // Readpixels uses the pack state and read FBO
Jamie Madillc67323a2017-11-02 23:11:41 -0400391 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_STATE);
Corentin Wallez29a20992017-11-06 18:23:16 -0500392 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 Madill71c88b32017-09-14 22:20:29 -0400454 ANGLE_TRY(zeroTexture.second->onDestroy(this));
Jamie Madill4928b7c2017-06-20 12:57:39 -0400455 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);
Yunchao Hea336b902017-08-02 16:05:21 +0800474 mState.mPipelines->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400475
Jamie Madill76e471e2017-10-21 09:56:01 -0400476 mImplementation->onDestroy(this);
477
Jamie Madill4928b7c2017-06-20 12:57:39 -0400478 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000479}
480
Jamie Madill70ee0f62017-02-06 16:04:20 -0500481Context::~Context()
482{
483}
484
Jamie Madill4928b7c2017-06-20 12:57:39 -0400485egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000486{
Jamie Madill61e16b42017-06-19 11:13:23 -0400487 mCurrentDisplay = display;
488
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000489 if (!mHasBeenCurrent)
490 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000491 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500492 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400493 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000494
Corentin Wallezc295e512017-01-27 17:47:50 -0500495 int width = 0;
496 int height = 0;
497 if (surface != nullptr)
498 {
499 width = surface->getWidth();
500 height = surface->getHeight();
501 }
502
503 mGLState.setViewportParams(0, 0, width, height);
504 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000505
506 mHasBeenCurrent = true;
507 }
508
Jamie Madill1b94d432015-08-07 13:23:23 -0400509 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700510 mGLState.setAllDirtyBits();
Jamie Madill81c2e252017-09-09 23:32:46 -0400511 mGLState.setAllDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -0400512
Jamie Madill4928b7c2017-06-20 12:57:39 -0400513 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500514
515 Framebuffer *newDefault = nullptr;
516 if (surface != nullptr)
517 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400518 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500519 mCurrentSurface = surface;
520 newDefault = surface->getDefaultFramebuffer();
521 }
522 else
523 {
524 if (mSurfacelessFramebuffer == nullptr)
525 {
526 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
527 }
528
529 newDefault = mSurfacelessFramebuffer;
530 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000531
Corentin Wallez37c39792015-08-20 14:19:46 -0400532 // Update default framebuffer, the binding of the previous default
533 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400534 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700535 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400536 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700537 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400538 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700539 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400540 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700541 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400542 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500543 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400544 }
Ian Ewell292f0052016-02-04 10:37:32 -0500545
546 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400547 mImplementation->onMakeCurrent(this);
548 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000549}
550
Jamie Madill4928b7c2017-06-20 12:57:39 -0400551egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400552{
Corentin Wallez37c39792015-08-20 14:19:46 -0400553 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500554 Framebuffer *currentDefault = nullptr;
555 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400556 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500557 currentDefault = mCurrentSurface->getDefaultFramebuffer();
558 }
559 else if (mSurfacelessFramebuffer != nullptr)
560 {
561 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400562 }
563
Corentin Wallezc295e512017-01-27 17:47:50 -0500564 if (mGLState.getReadFramebuffer() == currentDefault)
565 {
566 mGLState.setReadFramebufferBinding(nullptr);
567 }
568 if (mGLState.getDrawFramebuffer() == currentDefault)
569 {
570 mGLState.setDrawFramebufferBinding(nullptr);
571 }
572 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
573
574 if (mCurrentSurface)
575 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400576 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500577 mCurrentSurface = nullptr;
578 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400579
580 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400581}
582
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000583GLuint Context::createBuffer()
584{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500585 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000586}
587
588GLuint Context::createProgram()
589{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500590 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000591}
592
593GLuint Context::createShader(GLenum type)
594{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500595 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000596}
597
598GLuint Context::createTexture()
599{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500600 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000601}
602
603GLuint Context::createRenderbuffer()
604{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500605 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000606}
607
Sami Väisänene45e53b2016-05-25 10:36:04 +0300608GLuint Context::createPaths(GLsizei range)
609{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500610 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300611 if (resultOrError.isError())
612 {
613 handleError(resultOrError.getError());
614 return 0;
615 }
616 return resultOrError.getResult();
617}
618
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000619// Returns an unused framebuffer name
620GLuint Context::createFramebuffer()
621{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500622 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000623}
624
Jamie Madill33dc8432013-07-26 11:55:05 -0400625GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626{
Jamie Madill33dc8432013-07-26 11:55:05 -0400627 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400628 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629 return handle;
630}
631
Yunchao Hea336b902017-08-02 16:05:21 +0800632GLuint Context::createProgramPipeline()
633{
634 return mState.mPipelines->createProgramPipeline();
635}
636
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637void Context::deleteBuffer(GLuint buffer)
638{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500639 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000640 {
641 detachBuffer(buffer);
642 }
Jamie Madill893ab082014-05-16 16:56:10 -0400643
Jamie Madill6c1f6712017-02-14 19:08:04 -0500644 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000645}
646
647void Context::deleteShader(GLuint shader)
648{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500649 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000650}
651
652void Context::deleteProgram(GLuint program)
653{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500654 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000655}
656
657void Context::deleteTexture(GLuint texture)
658{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500659 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000660 {
661 detachTexture(texture);
662 }
663
Jamie Madill6c1f6712017-02-14 19:08:04 -0500664 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000665}
666
667void Context::deleteRenderbuffer(GLuint renderbuffer)
668{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500669 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000670 {
671 detachRenderbuffer(renderbuffer);
672 }
Jamie Madill893ab082014-05-16 16:56:10 -0400673
Jamie Madill6c1f6712017-02-14 19:08:04 -0500674 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000675}
676
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400677void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400678{
679 // The spec specifies the underlying Fence object is not deleted until all current
680 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
681 // and since our API is currently designed for being called from a single thread, we can delete
682 // the fence immediately.
Jamie Madill70b5bb02017-08-28 13:32:37 -0400683 mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400684}
685
Yunchao Hea336b902017-08-02 16:05:21 +0800686void Context::deleteProgramPipeline(GLuint pipeline)
687{
688 if (mState.mPipelines->getProgramPipeline(pipeline))
689 {
690 detachProgramPipeline(pipeline);
691 }
692
693 mState.mPipelines->deleteObject(this, pipeline);
694}
695
Sami Väisänene45e53b2016-05-25 10:36:04 +0300696void Context::deletePaths(GLuint first, GLsizei range)
697{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500698 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300699}
700
701bool Context::hasPathData(GLuint path) const
702{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500703 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300704 if (pathObj == nullptr)
705 return false;
706
707 return pathObj->hasPathData();
708}
709
710bool Context::hasPath(GLuint path) const
711{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500712 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300713}
714
715void Context::setPathCommands(GLuint path,
716 GLsizei numCommands,
717 const GLubyte *commands,
718 GLsizei numCoords,
719 GLenum coordType,
720 const void *coords)
721{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500722 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300723
724 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
725}
726
727void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
728{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500729 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300730
731 switch (pname)
732 {
733 case GL_PATH_STROKE_WIDTH_CHROMIUM:
734 pathObj->setStrokeWidth(value);
735 break;
736 case GL_PATH_END_CAPS_CHROMIUM:
737 pathObj->setEndCaps(static_cast<GLenum>(value));
738 break;
739 case GL_PATH_JOIN_STYLE_CHROMIUM:
740 pathObj->setJoinStyle(static_cast<GLenum>(value));
741 break;
742 case GL_PATH_MITER_LIMIT_CHROMIUM:
743 pathObj->setMiterLimit(value);
744 break;
745 case GL_PATH_STROKE_BOUND_CHROMIUM:
746 pathObj->setStrokeBound(value);
747 break;
748 default:
749 UNREACHABLE();
750 break;
751 }
752}
753
754void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
755{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500756 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300757
758 switch (pname)
759 {
760 case GL_PATH_STROKE_WIDTH_CHROMIUM:
761 *value = pathObj->getStrokeWidth();
762 break;
763 case GL_PATH_END_CAPS_CHROMIUM:
764 *value = static_cast<GLfloat>(pathObj->getEndCaps());
765 break;
766 case GL_PATH_JOIN_STYLE_CHROMIUM:
767 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
768 break;
769 case GL_PATH_MITER_LIMIT_CHROMIUM:
770 *value = pathObj->getMiterLimit();
771 break;
772 case GL_PATH_STROKE_BOUND_CHROMIUM:
773 *value = pathObj->getStrokeBound();
774 break;
775 default:
776 UNREACHABLE();
777 break;
778 }
779}
780
781void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
782{
783 mGLState.setPathStencilFunc(func, ref, mask);
784}
785
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000786void Context::deleteFramebuffer(GLuint framebuffer)
787{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500788 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000789 {
790 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000791 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500792
Jamie Madill6c1f6712017-02-14 19:08:04 -0500793 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794}
795
Jamie Madill33dc8432013-07-26 11:55:05 -0400796void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000797{
Jamie Madill96a483b2017-06-27 16:49:21 -0400798 FenceNV *fenceObject = nullptr;
799 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400801 mFenceNVHandleAllocator.release(fence);
802 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000803 }
804}
805
Geoff Lang70d0f492015-12-10 17:45:46 -0500806Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000807{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500808 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000809}
810
Jamie Madill570f7c82014-07-03 10:38:54 -0400811Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000812{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500813 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000814}
815
Geoff Lang70d0f492015-12-10 17:45:46 -0500816Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000817{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500818 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000819}
820
Jamie Madill70b5bb02017-08-28 13:32:37 -0400821Sync *Context::getSync(GLsync handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400822{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400823 return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400824}
825
Jamie Madill57a89722013-07-02 11:57:03 -0400826VertexArray *Context::getVertexArray(GLuint handle) const
827{
Jamie Madill96a483b2017-06-27 16:49:21 -0400828 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400829}
830
Jamie Madilldc356042013-07-19 16:36:57 -0400831Sampler *Context::getSampler(GLuint handle) const
832{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500833 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400834}
835
Geoff Langc8058452014-02-03 12:04:11 -0500836TransformFeedback *Context::getTransformFeedback(GLuint handle) const
837{
Jamie Madill96a483b2017-06-27 16:49:21 -0400838 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500839}
840
Yunchao Hea336b902017-08-02 16:05:21 +0800841ProgramPipeline *Context::getProgramPipeline(GLuint handle) const
842{
843 return mState.mPipelines->getProgramPipeline(handle);
844}
845
Geoff Lang70d0f492015-12-10 17:45:46 -0500846LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
847{
848 switch (identifier)
849 {
850 case GL_BUFFER:
851 return getBuffer(name);
852 case GL_SHADER:
853 return getShader(name);
854 case GL_PROGRAM:
855 return getProgram(name);
856 case GL_VERTEX_ARRAY:
857 return getVertexArray(name);
858 case GL_QUERY:
859 return getQuery(name);
860 case GL_TRANSFORM_FEEDBACK:
861 return getTransformFeedback(name);
862 case GL_SAMPLER:
863 return getSampler(name);
864 case GL_TEXTURE:
865 return getTexture(name);
866 case GL_RENDERBUFFER:
867 return getRenderbuffer(name);
868 case GL_FRAMEBUFFER:
869 return getFramebuffer(name);
870 default:
871 UNREACHABLE();
872 return nullptr;
873 }
874}
875
876LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
877{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400878 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
Geoff Lang70d0f492015-12-10 17:45:46 -0500879}
880
Martin Radev9d901792016-07-15 15:58:58 +0300881void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
882{
883 LabeledObject *object = getLabeledObject(identifier, name);
884 ASSERT(object != nullptr);
885
886 std::string labelName = GetObjectLabelFromPointer(length, label);
887 object->setLabel(labelName);
Jamie Madill8693bdb2017-09-02 15:32:14 -0400888
889 // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
890 // specified object is active until we do this.
891 mGLState.setObjectDirty(identifier);
Martin Radev9d901792016-07-15 15:58:58 +0300892}
893
894void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
895{
896 LabeledObject *object = getLabeledObjectFromPtr(ptr);
897 ASSERT(object != nullptr);
898
899 std::string labelName = GetObjectLabelFromPointer(length, label);
900 object->setLabel(labelName);
901}
902
903void Context::getObjectLabel(GLenum identifier,
904 GLuint name,
905 GLsizei bufSize,
906 GLsizei *length,
907 GLchar *label) const
908{
909 LabeledObject *object = getLabeledObject(identifier, name);
910 ASSERT(object != nullptr);
911
912 const std::string &objectLabel = object->getLabel();
913 GetObjectLabelBase(objectLabel, bufSize, length, label);
914}
915
916void Context::getObjectPtrLabel(const void *ptr,
917 GLsizei bufSize,
918 GLsizei *length,
919 GLchar *label) const
920{
921 LabeledObject *object = getLabeledObjectFromPtr(ptr);
922 ASSERT(object != nullptr);
923
924 const std::string &objectLabel = object->getLabel();
925 GetObjectLabelBase(objectLabel, bufSize, length, label);
926}
927
Jamie Madilldc356042013-07-19 16:36:57 -0400928bool Context::isSampler(GLuint samplerName) const
929{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500930 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400931}
932
Jamie Madilldedd7b92014-11-05 16:30:36 -0500933void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000934{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500935 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000936
Jamie Madilldedd7b92014-11-05 16:30:36 -0500937 if (handle == 0)
938 {
939 texture = mZeroTextures[target].get();
940 }
941 else
942 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500943 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500944 }
945
946 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400947 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000948}
949
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500950void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000951{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500952 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
953 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700954 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955}
956
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500957void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500959 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
960 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700961 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000962}
963
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500964void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400965{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500966 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700967 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400968}
969
Shao80957d92017-02-20 21:25:59 +0800970void Context::bindVertexBuffer(GLuint bindingIndex,
971 GLuint bufferHandle,
972 GLintptr offset,
973 GLsizei stride)
974{
975 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400976 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +0800977}
978
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500979void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400980{
Geoff Lang76b10c92014-09-05 16:28:14 -0400981 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400982 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500983 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400984 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400985}
986
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800987void Context::bindImageTexture(GLuint unit,
988 GLuint texture,
989 GLint level,
990 GLboolean layered,
991 GLint layer,
992 GLenum access,
993 GLenum format)
994{
995 Texture *tex = mState.mTextures->getTexture(texture);
996 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
997}
998
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999void Context::useProgram(GLuint program)
1000{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001001 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001002}
1003
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001004void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001005{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001006 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001007 TransformFeedback *transformFeedback =
1008 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001009 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001010}
1011
Yunchao Hea336b902017-08-02 16:05:21 +08001012void Context::bindProgramPipeline(GLuint pipelineHandle)
1013{
1014 ProgramPipeline *pipeline =
1015 mState.mPipelines->checkProgramPipelineAllocation(mImplementation.get(), pipelineHandle);
1016 mGLState.setProgramPipelineBinding(this, pipeline);
1017}
1018
Jamie Madillf0e04492017-08-26 15:28:42 -04001019void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001020{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001021 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001022 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001023
Geoff Lang5aad9672014-09-08 11:10:42 -04001024 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001025 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001026
1027 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001028 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001029}
1030
Jamie Madillf0e04492017-08-26 15:28:42 -04001031void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001032{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001033 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001034 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001035
Jamie Madillf0e04492017-08-26 15:28:42 -04001036 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001037
Geoff Lang5aad9672014-09-08 11:10:42 -04001038 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001039 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001040}
1041
Jamie Madillf0e04492017-08-26 15:28:42 -04001042void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001043{
1044 ASSERT(target == GL_TIMESTAMP_EXT);
1045
1046 Query *queryObject = getQuery(id, true, target);
1047 ASSERT(queryObject);
1048
Jamie Madillf0e04492017-08-26 15:28:42 -04001049 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001050}
1051
1052void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1053{
1054 switch (pname)
1055 {
1056 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001057 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001058 break;
1059 case GL_QUERY_COUNTER_BITS_EXT:
1060 switch (target)
1061 {
1062 case GL_TIME_ELAPSED_EXT:
1063 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1064 break;
1065 case GL_TIMESTAMP_EXT:
1066 params[0] = getExtensions().queryCounterBitsTimestamp;
1067 break;
1068 default:
1069 UNREACHABLE();
1070 params[0] = 0;
1071 break;
1072 }
1073 break;
1074 default:
1075 UNREACHABLE();
1076 return;
1077 }
1078}
1079
Geoff Lang2186c382016-10-14 10:54:54 -04001080void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001081{
Geoff Lang2186c382016-10-14 10:54:54 -04001082 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001083}
1084
Geoff Lang2186c382016-10-14 10:54:54 -04001085void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001086{
Geoff Lang2186c382016-10-14 10:54:54 -04001087 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001088}
1089
Geoff Lang2186c382016-10-14 10:54:54 -04001090void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001091{
Geoff Lang2186c382016-10-14 10:54:54 -04001092 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001093}
1094
Geoff Lang2186c382016-10-14 10:54:54 -04001095void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001096{
Geoff Lang2186c382016-10-14 10:54:54 -04001097 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001098}
1099
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001100Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001101{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001102 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001103}
1104
Jamie Madill2f348d22017-06-05 10:50:59 -04001105FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106{
Jamie Madill96a483b2017-06-27 16:49:21 -04001107 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001108}
1109
Jamie Madill2f348d22017-06-05 10:50:59 -04001110Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001111{
Jamie Madill96a483b2017-06-27 16:49:21 -04001112 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001113 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001114 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001115 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001116
1117 Query *query = mQueryMap.query(handle);
1118 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001119 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001120 query = new Query(mImplementation->createQuery(type), handle);
1121 query->addRef();
1122 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001123 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001124 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001125}
1126
Geoff Lang70d0f492015-12-10 17:45:46 -05001127Query *Context::getQuery(GLuint handle) const
1128{
Jamie Madill96a483b2017-06-27 16:49:21 -04001129 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001130}
1131
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001132Texture *Context::getTargetTexture(GLenum target) const
1133{
Ian Ewellbda75592016-04-18 17:25:54 -04001134 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001135 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001136}
1137
Geoff Lang76b10c92014-09-05 16:28:14 -04001138Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001139{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001140 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001141}
1142
Geoff Lang492a7e42014-11-05 13:27:06 -05001143Compiler *Context::getCompiler() const
1144{
Jamie Madill2f348d22017-06-05 10:50:59 -04001145 if (mCompiler.get() == nullptr)
1146 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001147 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001148 }
1149 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001150}
1151
Jamie Madillc1d770e2017-04-13 17:31:24 -04001152void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001153{
1154 switch (pname)
1155 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001156 case GL_SHADER_COMPILER:
1157 *params = GL_TRUE;
1158 break;
1159 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1160 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1161 break;
1162 default:
1163 mGLState.getBooleanv(pname, params);
1164 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001166}
1167
Jamie Madillc1d770e2017-04-13 17:31:24 -04001168void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001169{
Shannon Woods53a94a82014-06-24 15:20:36 -04001170 // Queries about context capabilities and maximums are answered by Context.
1171 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172 switch (pname)
1173 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001174 case GL_ALIASED_LINE_WIDTH_RANGE:
1175 params[0] = mCaps.minAliasedLineWidth;
1176 params[1] = mCaps.maxAliasedLineWidth;
1177 break;
1178 case GL_ALIASED_POINT_SIZE_RANGE:
1179 params[0] = mCaps.minAliasedPointSize;
1180 params[1] = mCaps.maxAliasedPointSize;
1181 break;
1182 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1183 ASSERT(mExtensions.textureFilterAnisotropic);
1184 *params = mExtensions.maxTextureAnisotropy;
1185 break;
1186 case GL_MAX_TEXTURE_LOD_BIAS:
1187 *params = mCaps.maxLODBias;
1188 break;
1189
1190 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1191 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1192 {
1193 ASSERT(mExtensions.pathRendering);
1194 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1195 memcpy(params, m, 16 * sizeof(GLfloat));
1196 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001197 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001198
Jamie Madill231c7f52017-04-26 13:45:37 -04001199 default:
1200 mGLState.getFloatv(pname, params);
1201 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001202 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001203}
1204
Jamie Madillc1d770e2017-04-13 17:31:24 -04001205void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206{
Shannon Woods53a94a82014-06-24 15:20:36 -04001207 // Queries about context capabilities and maximums are answered by Context.
1208 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001209
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210 switch (pname)
1211 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001212 case GL_MAX_VERTEX_ATTRIBS:
1213 *params = mCaps.maxVertexAttributes;
1214 break;
1215 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1216 *params = mCaps.maxVertexUniformVectors;
1217 break;
1218 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1219 *params = mCaps.maxVertexUniformComponents;
1220 break;
1221 case GL_MAX_VARYING_VECTORS:
1222 *params = mCaps.maxVaryingVectors;
1223 break;
1224 case GL_MAX_VARYING_COMPONENTS:
1225 *params = mCaps.maxVertexOutputComponents;
1226 break;
1227 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1228 *params = mCaps.maxCombinedTextureImageUnits;
1229 break;
1230 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1231 *params = mCaps.maxVertexTextureImageUnits;
1232 break;
1233 case GL_MAX_TEXTURE_IMAGE_UNITS:
1234 *params = mCaps.maxTextureImageUnits;
1235 break;
1236 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1237 *params = mCaps.maxFragmentUniformVectors;
1238 break;
1239 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1240 *params = mCaps.maxFragmentUniformComponents;
1241 break;
1242 case GL_MAX_RENDERBUFFER_SIZE:
1243 *params = mCaps.maxRenderbufferSize;
1244 break;
1245 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1246 *params = mCaps.maxColorAttachments;
1247 break;
1248 case GL_MAX_DRAW_BUFFERS_EXT:
1249 *params = mCaps.maxDrawBuffers;
1250 break;
1251 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1252 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1253 case GL_SUBPIXEL_BITS:
1254 *params = 4;
1255 break;
1256 case GL_MAX_TEXTURE_SIZE:
1257 *params = mCaps.max2DTextureSize;
1258 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001259 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1260 *params = mCaps.maxRectangleTextureSize;
1261 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001262 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1263 *params = mCaps.maxCubeMapTextureSize;
1264 break;
1265 case GL_MAX_3D_TEXTURE_SIZE:
1266 *params = mCaps.max3DTextureSize;
1267 break;
1268 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1269 *params = mCaps.maxArrayTextureLayers;
1270 break;
1271 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1272 *params = mCaps.uniformBufferOffsetAlignment;
1273 break;
1274 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1275 *params = mCaps.maxUniformBufferBindings;
1276 break;
1277 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1278 *params = mCaps.maxVertexUniformBlocks;
1279 break;
1280 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1281 *params = mCaps.maxFragmentUniformBlocks;
1282 break;
1283 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1284 *params = mCaps.maxCombinedTextureImageUnits;
1285 break;
1286 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1287 *params = mCaps.maxVertexOutputComponents;
1288 break;
1289 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1290 *params = mCaps.maxFragmentInputComponents;
1291 break;
1292 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1293 *params = mCaps.minProgramTexelOffset;
1294 break;
1295 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1296 *params = mCaps.maxProgramTexelOffset;
1297 break;
1298 case GL_MAJOR_VERSION:
1299 *params = getClientVersion().major;
1300 break;
1301 case GL_MINOR_VERSION:
1302 *params = getClientVersion().minor;
1303 break;
1304 case GL_MAX_ELEMENTS_INDICES:
1305 *params = mCaps.maxElementsIndices;
1306 break;
1307 case GL_MAX_ELEMENTS_VERTICES:
1308 *params = mCaps.maxElementsVertices;
1309 break;
1310 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1311 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1312 break;
1313 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1314 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1315 break;
1316 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1317 *params = mCaps.maxTransformFeedbackSeparateComponents;
1318 break;
1319 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1320 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1321 break;
1322 case GL_MAX_SAMPLES_ANGLE:
1323 *params = mCaps.maxSamples;
1324 break;
1325 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001327 params[0] = mCaps.maxViewportWidth;
1328 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001329 }
1330 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001331 case GL_COMPRESSED_TEXTURE_FORMATS:
1332 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1333 params);
1334 break;
1335 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1336 *params = mResetStrategy;
1337 break;
1338 case GL_NUM_SHADER_BINARY_FORMATS:
1339 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1340 break;
1341 case GL_SHADER_BINARY_FORMATS:
1342 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1343 break;
1344 case GL_NUM_PROGRAM_BINARY_FORMATS:
1345 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1346 break;
1347 case GL_PROGRAM_BINARY_FORMATS:
1348 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1349 break;
1350 case GL_NUM_EXTENSIONS:
1351 *params = static_cast<GLint>(mExtensionStrings.size());
1352 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001353
Jamie Madill231c7f52017-04-26 13:45:37 -04001354 // GL_KHR_debug
1355 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1356 *params = mExtensions.maxDebugMessageLength;
1357 break;
1358 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1359 *params = mExtensions.maxDebugLoggedMessages;
1360 break;
1361 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1362 *params = mExtensions.maxDebugGroupStackDepth;
1363 break;
1364 case GL_MAX_LABEL_LENGTH:
1365 *params = mExtensions.maxLabelLength;
1366 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001367
Martin Radeve5285d22017-07-14 16:23:53 +03001368 // GL_ANGLE_multiview
1369 case GL_MAX_VIEWS_ANGLE:
1370 *params = mExtensions.maxViews;
1371 break;
1372
Jamie Madill231c7f52017-04-26 13:45:37 -04001373 // GL_EXT_disjoint_timer_query
1374 case GL_GPU_DISJOINT_EXT:
1375 *params = mImplementation->getGPUDisjoint();
1376 break;
1377 case GL_MAX_FRAMEBUFFER_WIDTH:
1378 *params = mCaps.maxFramebufferWidth;
1379 break;
1380 case GL_MAX_FRAMEBUFFER_HEIGHT:
1381 *params = mCaps.maxFramebufferHeight;
1382 break;
1383 case GL_MAX_FRAMEBUFFER_SAMPLES:
1384 *params = mCaps.maxFramebufferSamples;
1385 break;
1386 case GL_MAX_SAMPLE_MASK_WORDS:
1387 *params = mCaps.maxSampleMaskWords;
1388 break;
1389 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1390 *params = mCaps.maxColorTextureSamples;
1391 break;
1392 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1393 *params = mCaps.maxDepthTextureSamples;
1394 break;
1395 case GL_MAX_INTEGER_SAMPLES:
1396 *params = mCaps.maxIntegerSamples;
1397 break;
1398 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1399 *params = mCaps.maxVertexAttribRelativeOffset;
1400 break;
1401 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1402 *params = mCaps.maxVertexAttribBindings;
1403 break;
1404 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1405 *params = mCaps.maxVertexAttribStride;
1406 break;
1407 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1408 *params = mCaps.maxVertexAtomicCounterBuffers;
1409 break;
1410 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1411 *params = mCaps.maxVertexAtomicCounters;
1412 break;
1413 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1414 *params = mCaps.maxVertexImageUniforms;
1415 break;
1416 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1417 *params = mCaps.maxVertexShaderStorageBlocks;
1418 break;
1419 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1420 *params = mCaps.maxFragmentAtomicCounterBuffers;
1421 break;
1422 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1423 *params = mCaps.maxFragmentAtomicCounters;
1424 break;
1425 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1426 *params = mCaps.maxFragmentImageUniforms;
1427 break;
1428 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1429 *params = mCaps.maxFragmentShaderStorageBlocks;
1430 break;
1431 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1432 *params = mCaps.minProgramTextureGatherOffset;
1433 break;
1434 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1435 *params = mCaps.maxProgramTextureGatherOffset;
1436 break;
1437 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1438 *params = mCaps.maxComputeWorkGroupInvocations;
1439 break;
1440 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1441 *params = mCaps.maxComputeUniformBlocks;
1442 break;
1443 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1444 *params = mCaps.maxComputeTextureImageUnits;
1445 break;
1446 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1447 *params = mCaps.maxComputeSharedMemorySize;
1448 break;
1449 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1450 *params = mCaps.maxComputeUniformComponents;
1451 break;
1452 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1453 *params = mCaps.maxComputeAtomicCounterBuffers;
1454 break;
1455 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1456 *params = mCaps.maxComputeAtomicCounters;
1457 break;
1458 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1459 *params = mCaps.maxComputeImageUniforms;
1460 break;
1461 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1462 *params = mCaps.maxCombinedComputeUniformComponents;
1463 break;
1464 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1465 *params = mCaps.maxComputeShaderStorageBlocks;
1466 break;
1467 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1468 *params = mCaps.maxCombinedShaderOutputResources;
1469 break;
1470 case GL_MAX_UNIFORM_LOCATIONS:
1471 *params = mCaps.maxUniformLocations;
1472 break;
1473 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1474 *params = mCaps.maxAtomicCounterBufferBindings;
1475 break;
1476 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1477 *params = mCaps.maxAtomicCounterBufferSize;
1478 break;
1479 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1480 *params = mCaps.maxCombinedAtomicCounterBuffers;
1481 break;
1482 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1483 *params = mCaps.maxCombinedAtomicCounters;
1484 break;
1485 case GL_MAX_IMAGE_UNITS:
1486 *params = mCaps.maxImageUnits;
1487 break;
1488 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1489 *params = mCaps.maxCombinedImageUniforms;
1490 break;
1491 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1492 *params = mCaps.maxShaderStorageBufferBindings;
1493 break;
1494 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1495 *params = mCaps.maxCombinedShaderStorageBlocks;
1496 break;
1497 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1498 *params = mCaps.shaderStorageBufferOffsetAlignment;
1499 break;
1500 default:
1501 mGLState.getIntegerv(this, pname, params);
1502 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001503 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001504}
1505
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001506void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001507{
Shannon Woods53a94a82014-06-24 15:20:36 -04001508 // Queries about context capabilities and maximums are answered by Context.
1509 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001510 switch (pname)
1511 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001512 case GL_MAX_ELEMENT_INDEX:
1513 *params = mCaps.maxElementIndex;
1514 break;
1515 case GL_MAX_UNIFORM_BLOCK_SIZE:
1516 *params = mCaps.maxUniformBlockSize;
1517 break;
1518 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1519 *params = mCaps.maxCombinedVertexUniformComponents;
1520 break;
1521 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1522 *params = mCaps.maxCombinedFragmentUniformComponents;
1523 break;
1524 case GL_MAX_SERVER_WAIT_TIMEOUT:
1525 *params = mCaps.maxServerWaitTimeout;
1526 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001527
Jamie Madill231c7f52017-04-26 13:45:37 -04001528 // GL_EXT_disjoint_timer_query
1529 case GL_TIMESTAMP_EXT:
1530 *params = mImplementation->getTimestamp();
1531 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001532
Jamie Madill231c7f52017-04-26 13:45:37 -04001533 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1534 *params = mCaps.maxShaderStorageBlockSize;
1535 break;
1536 default:
1537 UNREACHABLE();
1538 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001539 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001540}
1541
Geoff Lang70d0f492015-12-10 17:45:46 -05001542void Context::getPointerv(GLenum pname, void **params) const
1543{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001544 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001545}
1546
Martin Radev66fb8202016-07-28 11:45:20 +03001547void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001548{
Shannon Woods53a94a82014-06-24 15:20:36 -04001549 // Queries about context capabilities and maximums are answered by Context.
1550 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001551
1552 GLenum nativeType;
1553 unsigned int numParams;
1554 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1555 ASSERT(queryStatus);
1556
1557 if (nativeType == GL_INT)
1558 {
1559 switch (target)
1560 {
1561 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1562 ASSERT(index < 3u);
1563 *data = mCaps.maxComputeWorkGroupCount[index];
1564 break;
1565 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1566 ASSERT(index < 3u);
1567 *data = mCaps.maxComputeWorkGroupSize[index];
1568 break;
1569 default:
1570 mGLState.getIntegeri_v(target, index, data);
1571 }
1572 }
1573 else
1574 {
1575 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1576 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001577}
1578
Martin Radev66fb8202016-07-28 11:45:20 +03001579void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001580{
Shannon Woods53a94a82014-06-24 15:20:36 -04001581 // Queries about context capabilities and maximums are answered by Context.
1582 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001583
1584 GLenum nativeType;
1585 unsigned int numParams;
1586 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1587 ASSERT(queryStatus);
1588
1589 if (nativeType == GL_INT_64_ANGLEX)
1590 {
1591 mGLState.getInteger64i_v(target, index, data);
1592 }
1593 else
1594 {
1595 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1596 }
1597}
1598
1599void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1600{
1601 // Queries about context capabilities and maximums are answered by Context.
1602 // Queries about current GL state values are answered by State.
1603
1604 GLenum nativeType;
1605 unsigned int numParams;
1606 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1607 ASSERT(queryStatus);
1608
1609 if (nativeType == GL_BOOL)
1610 {
1611 mGLState.getBooleani_v(target, index, data);
1612 }
1613 else
1614 {
1615 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1616 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001617}
1618
Corentin Wallez336129f2017-10-17 15:55:40 -04001619void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params)
He Yunchao010e4db2017-03-03 14:22:06 +08001620{
1621 Buffer *buffer = mGLState.getTargetBuffer(target);
1622 QueryBufferParameteriv(buffer, pname, params);
1623}
1624
1625void Context::getFramebufferAttachmentParameteriv(GLenum target,
1626 GLenum attachment,
1627 GLenum pname,
1628 GLint *params)
1629{
1630 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1631 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1632}
1633
1634void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1635{
1636 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1637 QueryRenderbufferiv(this, renderbuffer, pname, params);
1638}
1639
1640void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1641{
1642 Texture *texture = getTargetTexture(target);
1643 QueryTexParameterfv(texture, pname, params);
1644}
1645
1646void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1647{
1648 Texture *texture = getTargetTexture(target);
1649 QueryTexParameteriv(texture, pname, params);
1650}
1651void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1652{
1653 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001654 SetTexParameterf(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001655 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001656}
1657
1658void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1659{
1660 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001661 SetTexParameterfv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001662 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001663}
1664
1665void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1666{
1667 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001668 SetTexParameteri(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001669 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001670}
1671
1672void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1673{
1674 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001675 SetTexParameteriv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001676 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001677}
1678
Jamie Madill675fe712016-12-19 13:07:54 -05001679void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001680{
Jamie Madill05b35b22017-10-03 09:01:44 -04001681 ANGLE_CONTEXT_TRY(prepareForDraw());
Jamie Madillb6664922017-07-25 12:55:04 -04001682 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1683 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001684}
1685
Jamie Madill675fe712016-12-19 13:07:54 -05001686void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001687{
Jamie Madill05b35b22017-10-03 09:01:44 -04001688 ANGLE_CONTEXT_TRY(prepareForDraw());
Jamie Madillb6664922017-07-25 12:55:04 -04001689 ANGLE_CONTEXT_TRY(
1690 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1691 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001692}
1693
Jamie Madill876429b2017-04-20 15:46:24 -04001694void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001695{
Jamie Madill05b35b22017-10-03 09:01:44 -04001696 ANGLE_CONTEXT_TRY(prepareForDraw());
Jamie Madillb6664922017-07-25 12:55:04 -04001697 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001698}
1699
Jamie Madill675fe712016-12-19 13:07:54 -05001700void Context::drawElementsInstanced(GLenum mode,
1701 GLsizei count,
1702 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001703 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001704 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001705{
Jamie Madill05b35b22017-10-03 09:01:44 -04001706 ANGLE_CONTEXT_TRY(prepareForDraw());
Jamie Madillb6664922017-07-25 12:55:04 -04001707 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001708 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001709}
1710
Jamie Madill675fe712016-12-19 13:07:54 -05001711void Context::drawRangeElements(GLenum mode,
1712 GLuint start,
1713 GLuint end,
1714 GLsizei count,
1715 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001716 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001717{
Jamie Madill05b35b22017-10-03 09:01:44 -04001718 ANGLE_CONTEXT_TRY(prepareForDraw());
Jamie Madillb6664922017-07-25 12:55:04 -04001719 ANGLE_CONTEXT_TRY(
1720 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001721}
1722
Jamie Madill876429b2017-04-20 15:46:24 -04001723void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001724{
Jamie Madill05b35b22017-10-03 09:01:44 -04001725 ANGLE_CONTEXT_TRY(prepareForDraw());
Jamie Madillb6664922017-07-25 12:55:04 -04001726 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001727}
1728
Jamie Madill876429b2017-04-20 15:46:24 -04001729void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001730{
Jamie Madill05b35b22017-10-03 09:01:44 -04001731 ANGLE_CONTEXT_TRY(prepareForDraw());
Jamie Madillb6664922017-07-25 12:55:04 -04001732 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001733}
1734
Jamie Madill675fe712016-12-19 13:07:54 -05001735void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001736{
Jamie Madill675fe712016-12-19 13:07:54 -05001737 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001738}
1739
Jamie Madill675fe712016-12-19 13:07:54 -05001740void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001741{
Jamie Madill675fe712016-12-19 13:07:54 -05001742 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001743}
1744
Austin Kinross6ee1e782015-05-29 17:05:37 -07001745void Context::insertEventMarker(GLsizei length, const char *marker)
1746{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001747 ASSERT(mImplementation);
1748 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001749}
1750
1751void Context::pushGroupMarker(GLsizei length, const char *marker)
1752{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001753 ASSERT(mImplementation);
1754 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001755}
1756
1757void Context::popGroupMarker()
1758{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001759 ASSERT(mImplementation);
1760 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001761}
1762
Geoff Langd8605522016-04-13 10:19:12 -04001763void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1764{
1765 Program *programObject = getProgram(program);
1766 ASSERT(programObject);
1767
1768 programObject->bindUniformLocation(location, name);
1769}
1770
Sami Väisänena797e062016-05-12 15:23:40 +03001771void Context::setCoverageModulation(GLenum components)
1772{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001773 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001774}
1775
Sami Väisänene45e53b2016-05-25 10:36:04 +03001776void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1777{
1778 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1779}
1780
1781void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1782{
1783 GLfloat I[16];
1784 angle::Matrix<GLfloat>::setToIdentity(I);
1785
1786 mGLState.loadPathRenderingMatrix(matrixMode, I);
1787}
1788
1789void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1790{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001791 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001792 if (!pathObj)
1793 return;
1794
1795 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1796 syncRendererState();
1797
1798 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1799}
1800
1801void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1802{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001803 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001804 if (!pathObj)
1805 return;
1806
1807 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1808 syncRendererState();
1809
1810 mImplementation->stencilStrokePath(pathObj, reference, mask);
1811}
1812
1813void Context::coverFillPath(GLuint path, GLenum coverMode)
1814{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001815 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001816 if (!pathObj)
1817 return;
1818
1819 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1820 syncRendererState();
1821
1822 mImplementation->coverFillPath(pathObj, coverMode);
1823}
1824
1825void Context::coverStrokePath(GLuint path, GLenum coverMode)
1826{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001827 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001828 if (!pathObj)
1829 return;
1830
1831 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1832 syncRendererState();
1833
1834 mImplementation->coverStrokePath(pathObj, coverMode);
1835}
1836
1837void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1838{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001839 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001840 if (!pathObj)
1841 return;
1842
1843 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1844 syncRendererState();
1845
1846 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1847}
1848
1849void Context::stencilThenCoverStrokePath(GLuint path,
1850 GLint reference,
1851 GLuint mask,
1852 GLenum coverMode)
1853{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001854 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001855 if (!pathObj)
1856 return;
1857
1858 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1859 syncRendererState();
1860
1861 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1862}
1863
Sami Väisänend59ca052016-06-21 16:10:00 +03001864void Context::coverFillPathInstanced(GLsizei numPaths,
1865 GLenum pathNameType,
1866 const void *paths,
1867 GLuint pathBase,
1868 GLenum coverMode,
1869 GLenum transformType,
1870 const GLfloat *transformValues)
1871{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001872 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001873
1874 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1875 syncRendererState();
1876
1877 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1878}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001879
Sami Väisänend59ca052016-06-21 16:10:00 +03001880void Context::coverStrokePathInstanced(GLsizei numPaths,
1881 GLenum pathNameType,
1882 const void *paths,
1883 GLuint pathBase,
1884 GLenum coverMode,
1885 GLenum transformType,
1886 const GLfloat *transformValues)
1887{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001888 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001889
1890 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1891 syncRendererState();
1892
1893 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1894 transformValues);
1895}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001896
Sami Väisänend59ca052016-06-21 16:10:00 +03001897void Context::stencilFillPathInstanced(GLsizei numPaths,
1898 GLenum pathNameType,
1899 const void *paths,
1900 GLuint pathBase,
1901 GLenum fillMode,
1902 GLuint mask,
1903 GLenum transformType,
1904 const GLfloat *transformValues)
1905{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001906 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001907
1908 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1909 syncRendererState();
1910
1911 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1912 transformValues);
1913}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001914
Sami Väisänend59ca052016-06-21 16:10:00 +03001915void Context::stencilStrokePathInstanced(GLsizei numPaths,
1916 GLenum pathNameType,
1917 const void *paths,
1918 GLuint pathBase,
1919 GLint reference,
1920 GLuint mask,
1921 GLenum transformType,
1922 const GLfloat *transformValues)
1923{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001924 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001925
1926 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1927 syncRendererState();
1928
1929 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1930 transformValues);
1931}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001932
Sami Väisänend59ca052016-06-21 16:10:00 +03001933void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1934 GLenum pathNameType,
1935 const void *paths,
1936 GLuint pathBase,
1937 GLenum fillMode,
1938 GLuint mask,
1939 GLenum coverMode,
1940 GLenum transformType,
1941 const GLfloat *transformValues)
1942{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001943 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001944
1945 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1946 syncRendererState();
1947
1948 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1949 transformType, transformValues);
1950}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001951
Sami Väisänend59ca052016-06-21 16:10:00 +03001952void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1953 GLenum pathNameType,
1954 const void *paths,
1955 GLuint pathBase,
1956 GLint reference,
1957 GLuint mask,
1958 GLenum coverMode,
1959 GLenum transformType,
1960 const GLfloat *transformValues)
1961{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001962 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001963
1964 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1965 syncRendererState();
1966
1967 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1968 transformType, transformValues);
1969}
1970
Sami Väisänen46eaa942016-06-29 10:26:37 +03001971void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1972{
1973 auto *programObject = getProgram(program);
1974
1975 programObject->bindFragmentInputLocation(location, name);
1976}
1977
1978void Context::programPathFragmentInputGen(GLuint program,
1979 GLint location,
1980 GLenum genMode,
1981 GLint components,
1982 const GLfloat *coeffs)
1983{
1984 auto *programObject = getProgram(program);
1985
Jamie Madillbd044ed2017-06-05 12:59:21 -04001986 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03001987}
1988
jchen1015015f72017-03-16 13:54:21 +08001989GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
1990{
jchen10fd7c3b52017-03-21 15:36:03 +08001991 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08001992 return QueryProgramResourceIndex(programObject, programInterface, name);
1993}
1994
jchen10fd7c3b52017-03-21 15:36:03 +08001995void Context::getProgramResourceName(GLuint program,
1996 GLenum programInterface,
1997 GLuint index,
1998 GLsizei bufSize,
1999 GLsizei *length,
2000 GLchar *name)
2001{
2002 const auto *programObject = getProgram(program);
2003 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2004}
2005
jchen10191381f2017-04-11 13:59:04 +08002006GLint Context::getProgramResourceLocation(GLuint program,
2007 GLenum programInterface,
2008 const GLchar *name)
2009{
2010 const auto *programObject = getProgram(program);
2011 return QueryProgramResourceLocation(programObject, programInterface, name);
2012}
2013
jchen10880683b2017-04-12 16:21:55 +08002014void Context::getProgramResourceiv(GLuint program,
2015 GLenum programInterface,
2016 GLuint index,
2017 GLsizei propCount,
2018 const GLenum *props,
2019 GLsizei bufSize,
2020 GLsizei *length,
2021 GLint *params)
2022{
2023 const auto *programObject = getProgram(program);
2024 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2025 length, params);
2026}
2027
jchen10d9cd7b72017-08-30 15:04:25 +08002028void Context::getProgramInterfaceiv(GLuint program,
2029 GLenum programInterface,
2030 GLenum pname,
2031 GLint *params)
2032{
2033 const auto *programObject = getProgram(program);
2034 QueryProgramInterfaceiv(programObject, programInterface, pname, params);
2035}
2036
Jamie Madill71c88b32017-09-14 22:20:29 -04002037void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002038{
Geoff Langda5777c2014-07-11 09:52:58 -04002039 if (error.isError())
2040 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002041 GLenum code = error.getCode();
2042 mErrors.insert(code);
2043 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2044 {
2045 markContextLost();
2046 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002047
Geoff Langee6884e2017-11-09 16:51:11 -05002048 ASSERT(!error.getMessage().empty());
2049 mGLState.getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2050 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Langda5777c2014-07-11 09:52:58 -04002051 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002052}
2053
2054// Get one of the recorded errors and clear its flag, if any.
2055// [OpenGL ES 2.0.24] section 2.5 page 13.
2056GLenum Context::getError()
2057{
Geoff Langda5777c2014-07-11 09:52:58 -04002058 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002059 {
Geoff Langda5777c2014-07-11 09:52:58 -04002060 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002061 }
Geoff Langda5777c2014-07-11 09:52:58 -04002062 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002063 {
Geoff Langda5777c2014-07-11 09:52:58 -04002064 GLenum error = *mErrors.begin();
2065 mErrors.erase(mErrors.begin());
2066 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002067 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002068}
2069
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002070// NOTE: this function should not assume that this context is current!
2071void Context::markContextLost()
2072{
2073 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002074 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002075 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002076 mContextLostForced = true;
2077 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002078 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002079}
2080
2081bool Context::isContextLost()
2082{
2083 return mContextLost;
2084}
2085
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002086GLenum Context::getResetStatus()
2087{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002088 // Even if the application doesn't want to know about resets, we want to know
2089 // as it will allow us to skip all the calls.
2090 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002091 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002092 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002093 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002094 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002095 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002096
2097 // EXT_robustness, section 2.6: If the reset notification behavior is
2098 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2099 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2100 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002101 }
2102
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002103 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2104 // status should be returned at least once, and GL_NO_ERROR should be returned
2105 // once the device has finished resetting.
2106 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002107 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002108 ASSERT(mResetStatus == GL_NO_ERROR);
2109 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002110
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002111 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002112 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002113 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002114 }
2115 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002116 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002117 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002118 // If markContextLost was used to mark the context lost then
2119 // assume that is not recoverable, and continue to report the
2120 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002121 mResetStatus = mImplementation->getResetStatus();
2122 }
Jamie Madill893ab082014-05-16 16:56:10 -04002123
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002124 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002125}
2126
2127bool Context::isResetNotificationEnabled()
2128{
2129 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2130}
2131
Corentin Walleze3b10e82015-05-20 11:06:25 -04002132const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002133{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002134 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002135}
2136
2137EGLenum Context::getClientType() const
2138{
2139 return mClientType;
2140}
2141
2142EGLenum Context::getRenderBuffer() const
2143{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002144 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2145 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002146 {
2147 return EGL_NONE;
2148 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002149
2150 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2151 ASSERT(backAttachment != nullptr);
2152 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002153}
2154
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002155VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002156{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002157 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002158 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2159 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002160 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002161 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2162 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002163
Jamie Madill96a483b2017-06-27 16:49:21 -04002164 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002165 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002166
2167 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002168}
2169
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002170TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002171{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002172 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002173 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2174 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002175 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002176 transformFeedback =
2177 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002178 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002179 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002180 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002181
2182 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002183}
2184
2185bool Context::isVertexArrayGenerated(GLuint vertexArray)
2186{
Jamie Madill96a483b2017-06-27 16:49:21 -04002187 ASSERT(mVertexArrayMap.contains(0));
2188 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002189}
2190
2191bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2192{
Jamie Madill96a483b2017-06-27 16:49:21 -04002193 ASSERT(mTransformFeedbackMap.contains(0));
2194 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002195}
2196
Shannon Woods53a94a82014-06-24 15:20:36 -04002197void Context::detachTexture(GLuint texture)
2198{
2199 // Simple pass-through to State's detachTexture method, as textures do not require
2200 // allocation map management either here or in the resource manager at detach time.
2201 // Zero textures are held by the Context, and we don't attempt to request them from
2202 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002203 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002204}
2205
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002206void Context::detachBuffer(GLuint buffer)
2207{
Yuly Novikov5807a532015-12-03 13:01:22 -05002208 // Simple pass-through to State's detachBuffer method, since
2209 // only buffer attachments to container objects that are bound to the current context
2210 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002211
Yuly Novikov5807a532015-12-03 13:01:22 -05002212 // [OpenGL ES 3.2] section 5.1.2 page 45:
2213 // Attachments to unbound container objects, such as
2214 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2215 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002216 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002217}
2218
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002219void Context::detachFramebuffer(GLuint framebuffer)
2220{
Shannon Woods53a94a82014-06-24 15:20:36 -04002221 // Framebuffer detachment is handled by Context, because 0 is a valid
2222 // Framebuffer object, and a pointer to it must be passed from Context
2223 // to State at binding time.
2224
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002225 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002226 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2227 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2228 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002229
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002230 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002231 {
2232 bindReadFramebuffer(0);
2233 }
2234
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002235 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002236 {
2237 bindDrawFramebuffer(0);
2238 }
2239}
2240
2241void Context::detachRenderbuffer(GLuint renderbuffer)
2242{
Jamie Madilla02315b2017-02-23 14:14:47 -05002243 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002244}
2245
Jamie Madill57a89722013-07-02 11:57:03 -04002246void Context::detachVertexArray(GLuint vertexArray)
2247{
Jamie Madill77a72f62015-04-14 11:18:32 -04002248 // Vertex array detachment is handled by Context, because 0 is a valid
2249 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002250 // binding time.
2251
Jamie Madill57a89722013-07-02 11:57:03 -04002252 // [OpenGL ES 3.0.2] section 2.10 page 43:
2253 // If a vertex array object that is currently bound is deleted, the binding
2254 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002255 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002256 {
2257 bindVertexArray(0);
2258 }
2259}
2260
Geoff Langc8058452014-02-03 12:04:11 -05002261void Context::detachTransformFeedback(GLuint transformFeedback)
2262{
Corentin Walleza2257da2016-04-19 16:43:12 -04002263 // Transform feedback detachment is handled by Context, because 0 is a valid
2264 // transform feedback, and a pointer to it must be passed from Context to State at
2265 // binding time.
2266
2267 // The OpenGL specification doesn't mention what should happen when the currently bound
2268 // transform feedback object is deleted. Since it is a container object, we treat it like
2269 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002270 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002271 {
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04002272 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Corentin Walleza2257da2016-04-19 16:43:12 -04002273 }
Geoff Langc8058452014-02-03 12:04:11 -05002274}
2275
Jamie Madilldc356042013-07-19 16:36:57 -04002276void Context::detachSampler(GLuint sampler)
2277{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002278 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002279}
2280
Yunchao Hea336b902017-08-02 16:05:21 +08002281void Context::detachProgramPipeline(GLuint pipeline)
2282{
2283 mGLState.detachProgramPipeline(this, pipeline);
2284}
2285
Jamie Madill3ef140a2017-08-26 23:11:21 -04002286void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002287{
Shaodde78e82017-05-22 14:13:27 +08002288 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002289}
2290
Jamie Madille29d1672013-07-19 16:36:57 -04002291void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2292{
Geoff Langc1984ed2016-10-07 12:41:00 -04002293 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002294 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002295 SetSamplerParameteri(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002296 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002297}
Jamie Madille29d1672013-07-19 16:36:57 -04002298
Geoff Langc1984ed2016-10-07 12:41:00 -04002299void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2300{
2301 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002302 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002303 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002304 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002305}
2306
2307void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2308{
Geoff Langc1984ed2016-10-07 12:41:00 -04002309 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002310 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002311 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002312 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002313}
2314
Geoff Langc1984ed2016-10-07 12:41:00 -04002315void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002316{
Geoff Langc1984ed2016-10-07 12:41:00 -04002317 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002318 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002319 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002320 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002321}
2322
Geoff Langc1984ed2016-10-07 12:41:00 -04002323void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002324{
Geoff Langc1984ed2016-10-07 12:41:00 -04002325 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002326 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002327 QuerySamplerParameteriv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002328 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002329}
Jamie Madill9675b802013-07-19 16:36:59 -04002330
Geoff Langc1984ed2016-10-07 12:41:00 -04002331void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2332{
2333 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002334 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002335 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002336 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002337}
2338
Olli Etuahof0fee072016-03-30 15:11:58 +03002339void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2340{
2341 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002342 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002343}
2344
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002345void Context::initRendererString()
2346{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002347 std::ostringstream rendererString;
2348 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002349 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002350 rendererString << ")";
2351
Geoff Langcec35902014-04-16 10:52:36 -04002352 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002353}
2354
Geoff Langc339c4e2016-11-29 10:37:36 -05002355void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002356{
Geoff Langc339c4e2016-11-29 10:37:36 -05002357 const Version &clientVersion = getClientVersion();
2358
2359 std::ostringstream versionString;
2360 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2361 << ANGLE_VERSION_STRING << ")";
2362 mVersionString = MakeStaticString(versionString.str());
2363
2364 std::ostringstream shadingLanguageVersionString;
2365 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2366 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2367 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2368 << ")";
2369 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002370}
2371
Geoff Langcec35902014-04-16 10:52:36 -04002372void Context::initExtensionStrings()
2373{
Geoff Langc339c4e2016-11-29 10:37:36 -05002374 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2375 std::ostringstream combinedStringStream;
2376 std::copy(strings.begin(), strings.end(),
2377 std::ostream_iterator<const char *>(combinedStringStream, " "));
2378 return MakeStaticString(combinedStringStream.str());
2379 };
2380
2381 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002382 for (const auto &extensionString : mExtensions.getStrings())
2383 {
2384 mExtensionStrings.push_back(MakeStaticString(extensionString));
2385 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002386 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002387
Bryan Bernhart58806562017-01-05 13:09:31 -08002388 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2389
Geoff Langc339c4e2016-11-29 10:37:36 -05002390 mRequestableExtensionStrings.clear();
2391 for (const auto &extensionInfo : GetExtensionInfoMap())
2392 {
2393 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002394 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2395 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002396 {
2397 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2398 }
2399 }
2400 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002401}
2402
Geoff Langc339c4e2016-11-29 10:37:36 -05002403const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002404{
Geoff Langc339c4e2016-11-29 10:37:36 -05002405 switch (name)
2406 {
2407 case GL_VENDOR:
2408 return reinterpret_cast<const GLubyte *>("Google Inc.");
2409
2410 case GL_RENDERER:
2411 return reinterpret_cast<const GLubyte *>(mRendererString);
2412
2413 case GL_VERSION:
2414 return reinterpret_cast<const GLubyte *>(mVersionString);
2415
2416 case GL_SHADING_LANGUAGE_VERSION:
2417 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2418
2419 case GL_EXTENSIONS:
2420 return reinterpret_cast<const GLubyte *>(mExtensionString);
2421
2422 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2423 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2424
2425 default:
2426 UNREACHABLE();
2427 return nullptr;
2428 }
Geoff Langcec35902014-04-16 10:52:36 -04002429}
2430
Geoff Langc339c4e2016-11-29 10:37:36 -05002431const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002432{
Geoff Langc339c4e2016-11-29 10:37:36 -05002433 switch (name)
2434 {
2435 case GL_EXTENSIONS:
2436 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2437
2438 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2439 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2440
2441 default:
2442 UNREACHABLE();
2443 return nullptr;
2444 }
Geoff Langcec35902014-04-16 10:52:36 -04002445}
2446
2447size_t Context::getExtensionStringCount() const
2448{
2449 return mExtensionStrings.size();
2450}
2451
Geoff Lang111a99e2017-10-17 10:58:41 -04002452bool Context::isExtensionRequestable(const char *name)
2453{
2454 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2455 auto extension = extensionInfos.find(name);
2456
2457 const Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2458 return extension != extensionInfos.end() && extension->second.Requestable &&
2459 nativeExtensions.*(extension->second.ExtensionsMember);
2460}
2461
Geoff Langc339c4e2016-11-29 10:37:36 -05002462void Context::requestExtension(const char *name)
2463{
2464 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2465 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2466 const auto &extension = extensionInfos.at(name);
2467 ASSERT(extension.Requestable);
Geoff Lang111a99e2017-10-17 10:58:41 -04002468 ASSERT(mImplementation->getNativeExtensions().*(extension.ExtensionsMember));
Geoff Langc339c4e2016-11-29 10:37:36 -05002469
2470 if (mExtensions.*(extension.ExtensionsMember))
2471 {
2472 // Extension already enabled
2473 return;
2474 }
2475
2476 mExtensions.*(extension.ExtensionsMember) = true;
2477 updateCaps();
2478 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002479
Jamie Madill2f348d22017-06-05 10:50:59 -04002480 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2481 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002482
Jamie Madill81c2e252017-09-09 23:32:46 -04002483 // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
2484 // sampleable.
2485 mState.mTextures->signalAllTexturesDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002486 for (auto &zeroTexture : mZeroTextures)
2487 {
Jamie Madill05b35b22017-10-03 09:01:44 -04002488 zeroTexture.second->signalDirty(InitState::Initialized);
Geoff Lang9aded172017-04-05 11:07:56 -04002489 }
2490
2491 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002492}
2493
2494size_t Context::getRequestableExtensionStringCount() const
2495{
2496 return mRequestableExtensionStrings.size();
2497}
2498
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002499void Context::beginTransformFeedback(GLenum primitiveMode)
2500{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002501 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002502 ASSERT(transformFeedback != nullptr);
2503 ASSERT(!transformFeedback->isPaused());
2504
Jamie Madill6c1f6712017-02-14 19:08:04 -05002505 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002506}
2507
2508bool Context::hasActiveTransformFeedback(GLuint program) const
2509{
2510 for (auto pair : mTransformFeedbackMap)
2511 {
2512 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2513 {
2514 return true;
2515 }
2516 }
2517 return false;
2518}
2519
Geoff Langb433e872017-10-05 14:01:47 -04002520void Context::initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit)
Geoff Lang493daf52014-07-03 13:38:44 -04002521{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002522 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002523
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002524 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002525
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002526 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002527
Geoff Langeb66a6e2016-10-31 13:06:12 -04002528 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002529 {
2530 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002531 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002532 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002533 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002534 mExtensions.multiview = false;
2535 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002536 }
2537
Geoff Langeb66a6e2016-10-31 13:06:12 -04002538 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002539 {
2540 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002541 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002542 }
2543
Jamie Madill00ed7a12016-05-19 13:13:38 -04002544 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002545 mExtensions.bindUniformLocation = true;
2546 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002547 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002548 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002549 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002550
2551 // Enable the no error extension if the context was created with the flag.
2552 mExtensions.noError = mSkipValidation;
2553
Corentin Wallezccab69d2017-01-27 16:57:15 -05002554 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002555 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002556
Geoff Lang70d0f492015-12-10 17:45:46 -05002557 // Explicitly enable GL_KHR_debug
2558 mExtensions.debug = true;
2559 mExtensions.maxDebugMessageLength = 1024;
2560 mExtensions.maxDebugLoggedMessages = 1024;
2561 mExtensions.maxDebugGroupStackDepth = 1024;
2562 mExtensions.maxLabelLength = 1024;
2563
Geoff Langff5b2d52016-09-07 11:32:23 -04002564 // Explicitly enable GL_ANGLE_robust_client_memory
2565 mExtensions.robustClientMemory = true;
2566
Jamie Madille08a1d32017-03-07 17:24:06 -05002567 // Determine robust resource init availability from EGL.
Geoff Langb433e872017-10-05 14:01:47 -04002568 mExtensions.robustResourceInitialization = robustResourceInit;
Jamie Madille08a1d32017-03-07 17:24:06 -05002569
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08002570 // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
2571 // supports it.
2572 mExtensions.robustBufferAccessBehavior =
2573 mRobustAccess && mExtensions.robustBufferAccessBehavior;
2574
Jamie Madillc43be722017-07-13 16:22:14 -04002575 // Enable the cache control query unconditionally.
2576 mExtensions.programCacheControl = true;
2577
Geoff Lang301d1612014-07-09 10:34:37 -04002578 // Apply implementation limits
Jamie Madill0f80ed82017-09-19 00:24:56 -04002579 LimitCap(&mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002580
Jamie Madill0f80ed82017-09-19 00:24:56 -04002581 if (getClientVersion() < ES_3_1)
2582 {
2583 mCaps.maxVertexAttribBindings = mCaps.maxVertexAttributes;
2584 }
2585 else
2586 {
2587 LimitCap(&mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2588 }
Geoff Lang301d1612014-07-09 10:34:37 -04002589
Jamie Madill0f80ed82017-09-19 00:24:56 -04002590 LimitCap(&mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2591 LimitCap(&mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2592 LimitCap(&mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2593
2594 // Limit textures as well, so we can use fast bitsets with texture bindings.
2595 LimitCap(&mCaps.maxCombinedTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES);
2596 LimitCap(&mCaps.maxVertexTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2);
2597 LimitCap(&mCaps.maxTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2);
Geoff Lang3a61c322014-07-10 13:01:54 -04002598
Jiawei Shaodb342272017-09-27 10:21:45 +08002599 mCaps.maxSampleMaskWords = std::min<GLuint>(mCaps.maxSampleMaskWords, MAX_SAMPLE_MASK_WORDS);
2600
Geoff Langc287ea62016-09-16 14:46:51 -04002601 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002602 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002603 for (const auto &extensionInfo : GetExtensionInfoMap())
2604 {
2605 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002606 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002607 {
2608 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2609 }
2610 }
2611
2612 // Generate texture caps
2613 updateCaps();
2614}
2615
2616void Context::updateCaps()
2617{
Geoff Lang900013c2014-07-07 11:32:19 -04002618 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002619 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002620
Jamie Madill7b62cf92017-11-02 15:20:49 -04002621 for (GLenum sizedInternalFormat : GetAllSizedInternalFormats())
Geoff Lang493daf52014-07-03 13:38:44 -04002622 {
Jamie Madill7b62cf92017-11-02 15:20:49 -04002623 TextureCaps formatCaps = mImplementation->getNativeTextureCaps().get(sizedInternalFormat);
Geoff Langca271392017-04-05 12:30:00 -04002624 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002625
Geoff Lang0d8b7242015-09-09 14:56:53 -04002626 // Update the format caps based on the client version and extensions.
2627 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2628 // ES3.
2629 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002630 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002631 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002632 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002633 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002634 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002635
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002636 // OpenGL ES does not support multisampling with non-rendererable formats
2637 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002638 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002639 (getClientVersion() < ES_3_1 &&
2640 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002641 {
Geoff Langd87878e2014-09-19 15:42:59 -04002642 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002643 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002644 else
2645 {
2646 // We may have limited the max samples for some required renderbuffer formats due to
2647 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2648 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2649
2650 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2651 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2652 // exception of signed and unsigned integer formats."
2653 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2654 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2655 {
2656 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2657 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2658 }
2659
2660 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2661 if (getClientVersion() >= ES_3_1)
2662 {
2663 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2664 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2665 // the exception that the signed and unsigned integer formats are required only to
2666 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2667 // multisamples, which must be at least one."
2668 if (formatInfo.componentType == GL_INT ||
2669 formatInfo.componentType == GL_UNSIGNED_INT)
2670 {
2671 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2672 }
2673
2674 // GLES 3.1 section 19.3.1.
2675 if (formatCaps.texturable)
2676 {
2677 if (formatInfo.depthBits > 0)
2678 {
2679 mCaps.maxDepthTextureSamples =
2680 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2681 }
2682 else if (formatInfo.redBits > 0)
2683 {
2684 mCaps.maxColorTextureSamples =
2685 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2686 }
2687 }
2688 }
2689 }
Geoff Langd87878e2014-09-19 15:42:59 -04002690
2691 if (formatCaps.texturable && formatInfo.compressed)
2692 {
Geoff Langca271392017-04-05 12:30:00 -04002693 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002694 }
2695
Geoff Langca271392017-04-05 12:30:00 -04002696 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002697 }
Jamie Madill32447362017-06-28 14:53:52 -04002698
2699 // If program binary is disabled, blank out the memory cache pointer.
2700 if (!mImplementation->getNativeExtensions().getProgramBinary)
2701 {
2702 mMemoryProgramCache = nullptr;
2703 }
Geoff Lang493daf52014-07-03 13:38:44 -04002704}
2705
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002706void Context::initWorkarounds()
2707{
Jamie Madill761b02c2017-06-23 16:27:06 -04002708 // Apply back-end workarounds.
2709 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2710
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002711 // Lose the context upon out of memory error if the application is
2712 // expecting to watch for those events.
2713 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2714}
2715
Jamie Madill05b35b22017-10-03 09:01:44 -04002716Error Context::prepareForDraw()
2717{
2718 syncRendererState();
Jamie Madilla59fc192017-11-02 12:57:58 -04002719
2720 if (isRobustResourceInitEnabled())
2721 {
2722 ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this));
2723 ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureDrawAttachmentsInitialized(this));
2724 }
2725
Jamie Madill05b35b22017-10-03 09:01:44 -04002726 return NoError();
2727}
2728
Jamie Madill1b94d432015-08-07 13:23:23 -04002729void Context::syncRendererState()
2730{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002731 mGLState.syncDirtyObjects(this);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002732 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002733 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002734 mGLState.clearDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -04002735}
2736
Jamie Madillad9f24e2016-02-12 09:27:24 -05002737void Context::syncRendererState(const State::DirtyBits &bitMask,
2738 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002739{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002740 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002741 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002742 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002743 mGLState.clearDirtyBits(dirtyBits);
Jamie Madill1b94d432015-08-07 13:23:23 -04002744}
Jamie Madillc29968b2016-01-20 11:17:23 -05002745
2746void Context::blitFramebuffer(GLint srcX0,
2747 GLint srcY0,
2748 GLint srcX1,
2749 GLint srcY1,
2750 GLint dstX0,
2751 GLint dstY0,
2752 GLint dstX1,
2753 GLint dstY1,
2754 GLbitfield mask,
2755 GLenum filter)
2756{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002757 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002758 ASSERT(drawFramebuffer);
2759
2760 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2761 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2762
Jamie Madillad9f24e2016-02-12 09:27:24 -05002763 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002764
Jamie Madillc564c072017-06-01 12:45:42 -04002765 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002766}
Jamie Madillc29968b2016-01-20 11:17:23 -05002767
2768void Context::clear(GLbitfield mask)
2769{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002770 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002771 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002772}
2773
2774void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2775{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002776 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002777 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002778}
2779
2780void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2781{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002782 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002783 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002784}
2785
2786void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2787{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002788 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002789 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002790}
2791
2792void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2793{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002794 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002795 ASSERT(framebufferObject);
2796
2797 // If a buffer is not present, the clear has no effect
2798 if (framebufferObject->getDepthbuffer() == nullptr &&
2799 framebufferObject->getStencilbuffer() == nullptr)
2800 {
2801 return;
2802 }
2803
Jamie Madillad9f24e2016-02-12 09:27:24 -05002804 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002805 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002806}
2807
2808void Context::readPixels(GLint x,
2809 GLint y,
2810 GLsizei width,
2811 GLsizei height,
2812 GLenum format,
2813 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002814 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002815{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002816 if (width == 0 || height == 0)
2817 {
2818 return;
2819 }
2820
Jamie Madillad9f24e2016-02-12 09:27:24 -05002821 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002822
Jamie Madillb6664922017-07-25 12:55:04 -04002823 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2824 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002825
2826 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002827 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002828}
2829
2830void Context::copyTexImage2D(GLenum target,
2831 GLint level,
2832 GLenum internalformat,
2833 GLint x,
2834 GLint y,
2835 GLsizei width,
2836 GLsizei height,
2837 GLint border)
2838{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002839 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002840 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002841
Jamie Madillc29968b2016-01-20 11:17:23 -05002842 Rectangle sourceArea(x, y, width, height);
2843
Jamie Madill05b35b22017-10-03 09:01:44 -04002844 Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002845 Texture *texture =
2846 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002847 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002848}
2849
2850void Context::copyTexSubImage2D(GLenum target,
2851 GLint level,
2852 GLint xoffset,
2853 GLint yoffset,
2854 GLint x,
2855 GLint y,
2856 GLsizei width,
2857 GLsizei height)
2858{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002859 if (width == 0 || height == 0)
2860 {
2861 return;
2862 }
2863
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002864 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002865 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002866
Jamie Madillc29968b2016-01-20 11:17:23 -05002867 Offset destOffset(xoffset, yoffset, 0);
2868 Rectangle sourceArea(x, y, width, height);
2869
Jamie Madill05b35b22017-10-03 09:01:44 -04002870 Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002871 Texture *texture =
2872 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002873 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002874}
2875
2876void Context::copyTexSubImage3D(GLenum target,
2877 GLint level,
2878 GLint xoffset,
2879 GLint yoffset,
2880 GLint zoffset,
2881 GLint x,
2882 GLint y,
2883 GLsizei width,
2884 GLsizei height)
2885{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002886 if (width == 0 || height == 0)
2887 {
2888 return;
2889 }
2890
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002891 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002892 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002893
Jamie Madillc29968b2016-01-20 11:17:23 -05002894 Offset destOffset(xoffset, yoffset, zoffset);
2895 Rectangle sourceArea(x, y, width, height);
2896
Jamie Madill05b35b22017-10-03 09:01:44 -04002897 Framebuffer *framebuffer = mGLState.getReadFramebuffer();
2898 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002899 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002900}
2901
2902void Context::framebufferTexture2D(GLenum target,
2903 GLenum attachment,
2904 GLenum textarget,
2905 GLuint texture,
2906 GLint level)
2907{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002908 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002909 ASSERT(framebuffer);
2910
2911 if (texture != 0)
2912 {
2913 Texture *textureObj = getTexture(texture);
2914
2915 ImageIndex index = ImageIndex::MakeInvalid();
2916
2917 if (textarget == GL_TEXTURE_2D)
2918 {
2919 index = ImageIndex::Make2D(level);
2920 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002921 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
2922 {
2923 index = ImageIndex::MakeRectangle(level);
2924 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002925 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2926 {
2927 ASSERT(level == 0);
2928 index = ImageIndex::Make2DMultisample();
2929 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002930 else
2931 {
2932 ASSERT(IsCubeMapTextureTarget(textarget));
2933 index = ImageIndex::MakeCube(textarget, level);
2934 }
2935
Jamie Madilla02315b2017-02-23 14:14:47 -05002936 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002937 }
2938 else
2939 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002940 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002941 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002942
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002943 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002944}
2945
2946void Context::framebufferRenderbuffer(GLenum target,
2947 GLenum attachment,
2948 GLenum renderbuffertarget,
2949 GLuint renderbuffer)
2950{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002951 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002952 ASSERT(framebuffer);
2953
2954 if (renderbuffer != 0)
2955 {
2956 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002957
2958 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002959 renderbufferObject);
2960 }
2961 else
2962 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002963 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002964 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002965
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002966 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002967}
2968
2969void Context::framebufferTextureLayer(GLenum target,
2970 GLenum attachment,
2971 GLuint texture,
2972 GLint level,
2973 GLint layer)
2974{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002975 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002976 ASSERT(framebuffer);
2977
2978 if (texture != 0)
2979 {
2980 Texture *textureObject = getTexture(texture);
2981
2982 ImageIndex index = ImageIndex::MakeInvalid();
2983
2984 if (textureObject->getTarget() == GL_TEXTURE_3D)
2985 {
2986 index = ImageIndex::Make3D(level, layer);
2987 }
2988 else
2989 {
2990 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2991 index = ImageIndex::Make2DArray(level, layer);
2992 }
2993
Jamie Madilla02315b2017-02-23 14:14:47 -05002994 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002995 }
2996 else
2997 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002998 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002999 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003000
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003001 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003002}
3003
Martin Radev137032d2017-07-13 10:11:12 +03003004void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3005 GLenum attachment,
3006 GLuint texture,
3007 GLint level,
3008 GLint baseViewIndex,
3009 GLsizei numViews)
3010{
Martin Radev82ef7742017-08-08 17:44:58 +03003011 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3012 ASSERT(framebuffer);
3013
3014 if (texture != 0)
3015 {
3016 Texture *textureObj = getTexture(texture);
3017
Martin Radev18b75ba2017-08-15 15:50:40 +03003018 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003019 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3020 numViews, baseViewIndex);
3021 }
3022 else
3023 {
3024 framebuffer->resetAttachment(this, attachment);
3025 }
3026
3027 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003028}
3029
3030void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3031 GLenum attachment,
3032 GLuint texture,
3033 GLint level,
3034 GLsizei numViews,
3035 const GLint *viewportOffsets)
3036{
Martin Radev5dae57b2017-07-14 16:15:55 +03003037 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3038 ASSERT(framebuffer);
3039
3040 if (texture != 0)
3041 {
3042 Texture *textureObj = getTexture(texture);
3043
3044 ImageIndex index = ImageIndex::Make2D(level);
3045 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3046 textureObj, numViews, viewportOffsets);
3047 }
3048 else
3049 {
3050 framebuffer->resetAttachment(this, attachment);
3051 }
3052
3053 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003054}
3055
Jamie Madillc29968b2016-01-20 11:17:23 -05003056void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3057{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003058 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003059 ASSERT(framebuffer);
3060 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003061 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003062}
3063
3064void Context::readBuffer(GLenum mode)
3065{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003066 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003067 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003068 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003069}
3070
3071void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3072{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003073 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003074 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003075
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003076 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003077 ASSERT(framebuffer);
3078
3079 // The specification isn't clear what should be done when the framebuffer isn't complete.
3080 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003081 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003082}
3083
3084void Context::invalidateFramebuffer(GLenum target,
3085 GLsizei numAttachments,
3086 const GLenum *attachments)
3087{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003088 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003089 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003090
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003091 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003092 ASSERT(framebuffer);
3093
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003094 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003095 {
Jamie Madill437fa652016-05-03 15:13:24 -04003096 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003097 }
Jamie Madill437fa652016-05-03 15:13:24 -04003098
Jamie Madill4928b7c2017-06-20 12:57:39 -04003099 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003100}
3101
3102void Context::invalidateSubFramebuffer(GLenum target,
3103 GLsizei numAttachments,
3104 const GLenum *attachments,
3105 GLint x,
3106 GLint y,
3107 GLsizei width,
3108 GLsizei height)
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
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003116 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003117 {
Jamie Madill437fa652016-05-03 15:13:24 -04003118 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003119 }
Jamie Madill437fa652016-05-03 15:13:24 -04003120
3121 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003122 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003123}
3124
Jamie Madill73a84962016-02-12 09:27:23 -05003125void Context::texImage2D(GLenum target,
3126 GLint level,
3127 GLint internalformat,
3128 GLsizei width,
3129 GLsizei height,
3130 GLint border,
3131 GLenum format,
3132 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003133 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003134{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003135 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003136
3137 Extents size(width, height, 1);
3138 Texture *texture =
3139 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003140 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3141 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003142}
3143
3144void Context::texImage3D(GLenum target,
3145 GLint level,
3146 GLint internalformat,
3147 GLsizei width,
3148 GLsizei height,
3149 GLsizei depth,
3150 GLint border,
3151 GLenum format,
3152 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003153 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003154{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003155 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003156
3157 Extents size(width, height, depth);
3158 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003159 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3160 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003161}
3162
3163void Context::texSubImage2D(GLenum target,
3164 GLint level,
3165 GLint xoffset,
3166 GLint yoffset,
3167 GLsizei width,
3168 GLsizei height,
3169 GLenum format,
3170 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003171 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003172{
3173 // Zero sized uploads are valid but no-ops
3174 if (width == 0 || height == 0)
3175 {
3176 return;
3177 }
3178
Jamie Madillad9f24e2016-02-12 09:27:24 -05003179 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003180
3181 Box area(xoffset, yoffset, 0, width, height, 1);
3182 Texture *texture =
3183 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003184 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3185 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003186}
3187
3188void Context::texSubImage3D(GLenum target,
3189 GLint level,
3190 GLint xoffset,
3191 GLint yoffset,
3192 GLint zoffset,
3193 GLsizei width,
3194 GLsizei height,
3195 GLsizei depth,
3196 GLenum format,
3197 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003198 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003199{
3200 // Zero sized uploads are valid but no-ops
3201 if (width == 0 || height == 0 || depth == 0)
3202 {
3203 return;
3204 }
3205
Jamie Madillad9f24e2016-02-12 09:27:24 -05003206 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003207
3208 Box area(xoffset, yoffset, zoffset, width, height, depth);
3209 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003210 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3211 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003212}
3213
3214void Context::compressedTexImage2D(GLenum target,
3215 GLint level,
3216 GLenum internalformat,
3217 GLsizei width,
3218 GLsizei height,
3219 GLint border,
3220 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003221 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003222{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003223 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003224
3225 Extents size(width, height, 1);
3226 Texture *texture =
3227 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003228 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003229 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003230 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003231}
3232
3233void Context::compressedTexImage3D(GLenum target,
3234 GLint level,
3235 GLenum internalformat,
3236 GLsizei width,
3237 GLsizei height,
3238 GLsizei depth,
3239 GLint border,
3240 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003241 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003242{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003243 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003244
3245 Extents size(width, height, depth);
3246 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003247 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003248 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003249 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003250}
3251
3252void Context::compressedTexSubImage2D(GLenum target,
3253 GLint level,
3254 GLint xoffset,
3255 GLint yoffset,
3256 GLsizei width,
3257 GLsizei height,
3258 GLenum format,
3259 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003260 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003261{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003262 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003263
3264 Box area(xoffset, yoffset, 0, width, height, 1);
3265 Texture *texture =
3266 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003267 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003268 format, imageSize,
3269 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003270}
3271
3272void Context::compressedTexSubImage3D(GLenum target,
3273 GLint level,
3274 GLint xoffset,
3275 GLint yoffset,
3276 GLint zoffset,
3277 GLsizei width,
3278 GLsizei height,
3279 GLsizei depth,
3280 GLenum format,
3281 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003282 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003283{
3284 // Zero sized uploads are valid but no-ops
3285 if (width == 0 || height == 0)
3286 {
3287 return;
3288 }
3289
Jamie Madillad9f24e2016-02-12 09:27:24 -05003290 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003291
3292 Box area(xoffset, yoffset, zoffset, width, height, depth);
3293 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003294 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003295 format, imageSize,
3296 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003297}
3298
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003299void Context::generateMipmap(GLenum target)
3300{
3301 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003302 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003303}
3304
Geoff Lang97073d12016-04-20 10:42:34 -07003305void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003306 GLint sourceLevel,
3307 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003308 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003309 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003310 GLint internalFormat,
3311 GLenum destType,
3312 GLboolean unpackFlipY,
3313 GLboolean unpackPremultiplyAlpha,
3314 GLboolean unpackUnmultiplyAlpha)
3315{
3316 syncStateForTexImage();
3317
3318 gl::Texture *sourceTexture = getTexture(sourceId);
3319 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003320 handleError(destTexture->copyTexture(
3321 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3322 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003323}
3324
3325void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003326 GLint sourceLevel,
3327 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003328 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003329 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003330 GLint xoffset,
3331 GLint yoffset,
3332 GLint x,
3333 GLint y,
3334 GLsizei width,
3335 GLsizei height,
3336 GLboolean unpackFlipY,
3337 GLboolean unpackPremultiplyAlpha,
3338 GLboolean unpackUnmultiplyAlpha)
3339{
3340 // Zero sized copies are valid but no-ops
3341 if (width == 0 || height == 0)
3342 {
3343 return;
3344 }
3345
3346 syncStateForTexImage();
3347
3348 gl::Texture *sourceTexture = getTexture(sourceId);
3349 gl::Texture *destTexture = getTexture(destId);
3350 Offset offset(xoffset, yoffset, 0);
3351 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003352 handleError(destTexture->copySubTexture(
3353 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3354 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003355}
3356
Geoff Lang47110bf2016-04-20 11:13:22 -07003357void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3358{
3359 syncStateForTexImage();
3360
3361 gl::Texture *sourceTexture = getTexture(sourceId);
3362 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003363 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003364}
3365
Corentin Wallez336129f2017-10-17 15:55:40 -04003366void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003367{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003368 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003369 ASSERT(buffer);
3370
Geoff Lang496c02d2016-10-20 11:38:11 -07003371 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003372}
3373
Corentin Wallez336129f2017-10-17 15:55:40 -04003374void *Context::mapBuffer(BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003375{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003376 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003377 ASSERT(buffer);
3378
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003379 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003380 if (error.isError())
3381 {
Jamie Madill437fa652016-05-03 15:13:24 -04003382 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003383 return nullptr;
3384 }
3385
3386 return buffer->getMapPointer();
3387}
3388
Corentin Wallez336129f2017-10-17 15:55:40 -04003389GLboolean Context::unmapBuffer(BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003390{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003391 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003392 ASSERT(buffer);
3393
3394 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003395 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003396 if (error.isError())
3397 {
Jamie Madill437fa652016-05-03 15:13:24 -04003398 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003399 return GL_FALSE;
3400 }
3401
3402 return result;
3403}
3404
Corentin Wallez336129f2017-10-17 15:55:40 -04003405void *Context::mapBufferRange(BufferBinding target,
3406 GLintptr offset,
3407 GLsizeiptr length,
3408 GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003409{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003410 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003411 ASSERT(buffer);
3412
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003413 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003414 if (error.isError())
3415 {
Jamie Madill437fa652016-05-03 15:13:24 -04003416 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003417 return nullptr;
3418 }
3419
3420 return buffer->getMapPointer();
3421}
3422
Corentin Wallez336129f2017-10-17 15:55:40 -04003423void Context::flushMappedBufferRange(BufferBinding /*target*/,
3424 GLintptr /*offset*/,
3425 GLsizeiptr /*length*/)
Olli Etuaho4f667482016-03-30 15:56:35 +03003426{
3427 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3428}
3429
Jamie Madillad9f24e2016-02-12 09:27:24 -05003430void Context::syncStateForReadPixels()
3431{
3432 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3433}
3434
3435void Context::syncStateForTexImage()
3436{
3437 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3438}
3439
3440void Context::syncStateForClear()
3441{
3442 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3443}
3444
3445void Context::syncStateForBlit()
3446{
3447 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3448}
3449
Jamie Madillc20ab272016-06-09 07:20:46 -07003450void Context::activeTexture(GLenum texture)
3451{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003452 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003453}
3454
Jamie Madill876429b2017-04-20 15:46:24 -04003455void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003456{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003457 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003458}
3459
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003460void Context::blendEquation(GLenum mode)
3461{
3462 mGLState.setBlendEquation(mode, mode);
3463}
3464
Jamie Madillc20ab272016-06-09 07:20:46 -07003465void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3466{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003467 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003468}
3469
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003470void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3471{
3472 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3473}
3474
Jamie Madillc20ab272016-06-09 07:20:46 -07003475void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3476{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003477 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003478}
3479
Jamie Madill876429b2017-04-20 15:46:24 -04003480void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003481{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003482 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003483}
3484
Jamie Madill876429b2017-04-20 15:46:24 -04003485void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003486{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003487 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003488}
3489
3490void Context::clearStencil(GLint s)
3491{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003492 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003493}
3494
3495void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3496{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003497 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003498}
3499
Corentin Wallez2e568cf2017-09-18 17:05:22 -04003500void Context::cullFace(CullFaceMode mode)
Jamie Madillc20ab272016-06-09 07:20:46 -07003501{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003502 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003503}
3504
3505void Context::depthFunc(GLenum func)
3506{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003507 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003508}
3509
3510void Context::depthMask(GLboolean flag)
3511{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003512 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003513}
3514
Jamie Madill876429b2017-04-20 15:46:24 -04003515void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003516{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003517 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003518}
3519
3520void Context::disable(GLenum cap)
3521{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003522 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003523}
3524
3525void Context::disableVertexAttribArray(GLuint index)
3526{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003527 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003528}
3529
3530void Context::enable(GLenum cap)
3531{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003532 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003533}
3534
3535void Context::enableVertexAttribArray(GLuint index)
3536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003538}
3539
3540void Context::frontFace(GLenum mode)
3541{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003542 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003543}
3544
3545void Context::hint(GLenum target, GLenum mode)
3546{
3547 switch (target)
3548 {
3549 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003551 break;
3552
3553 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003554 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003555 break;
3556
3557 default:
3558 UNREACHABLE();
3559 return;
3560 }
3561}
3562
3563void Context::lineWidth(GLfloat width)
3564{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003565 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003566}
3567
3568void Context::pixelStorei(GLenum pname, GLint param)
3569{
3570 switch (pname)
3571 {
3572 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003573 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003574 break;
3575
3576 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003577 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003578 break;
3579
3580 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003581 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003582 break;
3583
3584 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003585 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003586 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003587 break;
3588
3589 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003590 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003591 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003592 break;
3593
3594 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003595 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003596 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003597 break;
3598
3599 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003600 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003601 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003602 break;
3603
3604 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003605 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003606 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003607 break;
3608
3609 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003610 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003611 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003612 break;
3613
3614 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003615 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003616 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003617 break;
3618
3619 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003620 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003621 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003622 break;
3623
3624 default:
3625 UNREACHABLE();
3626 return;
3627 }
3628}
3629
3630void Context::polygonOffset(GLfloat factor, GLfloat units)
3631{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003632 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003633}
3634
Jamie Madill876429b2017-04-20 15:46:24 -04003635void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003636{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003637 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003638}
3639
Jiawei Shaodb342272017-09-27 10:21:45 +08003640void Context::sampleMaski(GLuint maskNumber, GLbitfield mask)
3641{
3642 mGLState.setSampleMaskParams(maskNumber, mask);
3643}
3644
Jamie Madillc20ab272016-06-09 07:20:46 -07003645void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3646{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003647 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003648}
3649
3650void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3651{
3652 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3653 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003654 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003655 }
3656
3657 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3658 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003659 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003660 }
3661}
3662
3663void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3664{
3665 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3666 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003667 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003668 }
3669
3670 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3671 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003672 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003673 }
3674}
3675
3676void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3677{
3678 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3679 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003680 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003681 }
3682
3683 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3684 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003685 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003686 }
3687}
3688
3689void Context::vertexAttrib1f(GLuint index, GLfloat x)
3690{
3691 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003692 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003693}
3694
3695void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3696{
3697 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003698 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003699}
3700
3701void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3702{
3703 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003704 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003705}
3706
3707void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3708{
3709 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003710 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003711}
3712
3713void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3714{
3715 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003716 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003717}
3718
3719void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3720{
3721 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003722 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003723}
3724
3725void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3726{
3727 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003728 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003729}
3730
3731void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3732{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003733 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003734}
3735
3736void Context::vertexAttribPointer(GLuint index,
3737 GLint size,
3738 GLenum type,
3739 GLboolean normalized,
3740 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003741 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003742{
Corentin Wallez336129f2017-10-17 15:55:40 -04003743 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array),
3744 size, type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003745}
3746
Shao80957d92017-02-20 21:25:59 +08003747void Context::vertexAttribFormat(GLuint attribIndex,
3748 GLint size,
3749 GLenum type,
3750 GLboolean normalized,
3751 GLuint relativeOffset)
3752{
3753 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3754 relativeOffset);
3755}
3756
3757void Context::vertexAttribIFormat(GLuint attribIndex,
3758 GLint size,
3759 GLenum type,
3760 GLuint relativeOffset)
3761{
3762 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3763}
3764
3765void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3766{
Shaodde78e82017-05-22 14:13:27 +08003767 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003768}
3769
3770void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3771{
3772 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3773}
3774
Jamie Madillc20ab272016-06-09 07:20:46 -07003775void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3776{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003777 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003778}
3779
3780void Context::vertexAttribIPointer(GLuint index,
3781 GLint size,
3782 GLenum type,
3783 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003784 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003785{
Corentin Wallez336129f2017-10-17 15:55:40 -04003786 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array),
3787 size, type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003788}
3789
3790void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3791{
3792 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003793 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003794}
3795
3796void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3797{
3798 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003799 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003800}
3801
3802void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3803{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003804 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003805}
3806
3807void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3808{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003809 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003810}
3811
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003812void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3813{
3814 const VertexAttribCurrentValueData &currentValues =
3815 getGLState().getVertexAttribCurrentValue(index);
3816 const VertexArray *vao = getGLState().getVertexArray();
3817 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3818 currentValues, pname, params);
3819}
3820
3821void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3822{
3823 const VertexAttribCurrentValueData &currentValues =
3824 getGLState().getVertexAttribCurrentValue(index);
3825 const VertexArray *vao = getGLState().getVertexArray();
3826 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3827 currentValues, pname, params);
3828}
3829
3830void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3831{
3832 const VertexAttribCurrentValueData &currentValues =
3833 getGLState().getVertexAttribCurrentValue(index);
3834 const VertexArray *vao = getGLState().getVertexArray();
3835 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3836 currentValues, pname, params);
3837}
3838
3839void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3840{
3841 const VertexAttribCurrentValueData &currentValues =
3842 getGLState().getVertexAttribCurrentValue(index);
3843 const VertexArray *vao = getGLState().getVertexArray();
3844 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3845 currentValues, pname, params);
3846}
3847
Jamie Madill876429b2017-04-20 15:46:24 -04003848void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003849{
3850 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3851 QueryVertexAttribPointerv(attrib, pname, pointer);
3852}
3853
Jamie Madillc20ab272016-06-09 07:20:46 -07003854void Context::debugMessageControl(GLenum source,
3855 GLenum type,
3856 GLenum severity,
3857 GLsizei count,
3858 const GLuint *ids,
3859 GLboolean enabled)
3860{
3861 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003862 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3863 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003864}
3865
3866void Context::debugMessageInsert(GLenum source,
3867 GLenum type,
3868 GLuint id,
3869 GLenum severity,
3870 GLsizei length,
3871 const GLchar *buf)
3872{
3873 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003874 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003875}
3876
3877void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3878{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003879 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003880}
3881
3882GLuint Context::getDebugMessageLog(GLuint count,
3883 GLsizei bufSize,
3884 GLenum *sources,
3885 GLenum *types,
3886 GLuint *ids,
3887 GLenum *severities,
3888 GLsizei *lengths,
3889 GLchar *messageLog)
3890{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003891 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3892 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003893}
3894
3895void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3896{
3897 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003898 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003899}
3900
3901void Context::popDebugGroup()
3902{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003903 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003904}
3905
Corentin Wallez336129f2017-10-17 15:55:40 -04003906void Context::bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04003907{
3908 Buffer *buffer = mGLState.getTargetBuffer(target);
3909 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003910 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003911}
3912
Corentin Wallez336129f2017-10-17 15:55:40 -04003913void Context::bufferSubData(BufferBinding target,
3914 GLintptr offset,
3915 GLsizeiptr size,
3916 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003917{
3918 if (data == nullptr)
3919 {
3920 return;
3921 }
3922
3923 Buffer *buffer = mGLState.getTargetBuffer(target);
3924 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003925 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003926}
3927
Jamie Madillef300b12016-10-07 15:12:09 -04003928void Context::attachShader(GLuint program, GLuint shader)
3929{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003930 auto programObject = mState.mShaderPrograms->getProgram(program);
3931 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003932 ASSERT(programObject && shaderObject);
3933 programObject->attachShader(shaderObject);
3934}
3935
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003936const Workarounds &Context::getWorkarounds() const
3937{
3938 return mWorkarounds;
3939}
3940
Corentin Wallez336129f2017-10-17 15:55:40 -04003941void Context::copyBufferSubData(BufferBinding readTarget,
3942 BufferBinding writeTarget,
Jamie Madillb0817d12016-11-01 15:48:31 -04003943 GLintptr readOffset,
3944 GLintptr writeOffset,
3945 GLsizeiptr size)
3946{
3947 // if size is zero, the copy is a successful no-op
3948 if (size == 0)
3949 {
3950 return;
3951 }
3952
3953 // TODO(jmadill): cache these.
3954 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3955 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3956
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003957 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003958}
3959
Jamie Madill01a80ee2016-11-07 12:06:18 -05003960void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3961{
3962 Program *programObject = getProgram(program);
3963 // TODO(jmadill): Re-use this from the validation if possible.
3964 ASSERT(programObject);
3965 programObject->bindAttributeLocation(index, name);
3966}
3967
Corentin Wallez336129f2017-10-17 15:55:40 -04003968void Context::bindBuffer(BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05003969{
Corentin Wallez336129f2017-10-17 15:55:40 -04003970 Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
3971 mGLState.setBufferBinding(this, target, bufferObject);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003972}
3973
Corentin Wallez336129f2017-10-17 15:55:40 -04003974void Context::bindBufferBase(BufferBinding target, GLuint index, GLuint buffer)
Jiajia Qin6eafb042016-12-27 17:04:07 +08003975{
3976 bindBufferRange(target, index, buffer, 0, 0);
3977}
3978
Corentin Wallez336129f2017-10-17 15:55:40 -04003979void Context::bindBufferRange(BufferBinding target,
Jiajia Qin6eafb042016-12-27 17:04:07 +08003980 GLuint index,
3981 GLuint buffer,
3982 GLintptr offset,
3983 GLsizeiptr size)
3984{
Corentin Wallez336129f2017-10-17 15:55:40 -04003985 Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
3986 mGLState.setIndexedBufferBinding(this, target, index, bufferObject, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08003987}
3988
Jamie Madill01a80ee2016-11-07 12:06:18 -05003989void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3990{
3991 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3992 {
3993 bindReadFramebuffer(framebuffer);
3994 }
3995
3996 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3997 {
3998 bindDrawFramebuffer(framebuffer);
3999 }
4000}
4001
4002void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4003{
4004 ASSERT(target == GL_RENDERBUFFER);
4005 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004006 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004007 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004008}
4009
JiangYizhoubddc46b2016-12-09 09:50:51 +08004010void Context::texStorage2DMultisample(GLenum target,
4011 GLsizei samples,
4012 GLenum internalformat,
4013 GLsizei width,
4014 GLsizei height,
4015 GLboolean fixedsamplelocations)
4016{
4017 Extents size(width, height, 1);
4018 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004019 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004020 fixedsamplelocations));
4021}
4022
4023void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4024{
JiangYizhou5b03f472017-01-09 10:22:53 +08004025 // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
4026 // the sample position should be queried by DRAW_FRAMEBUFFER.
4027 mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER);
4028 const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
JiangYizhoubddc46b2016-12-09 09:50:51 +08004029
4030 switch (pname)
4031 {
4032 case GL_SAMPLE_POSITION:
4033 handleError(framebuffer->getSamplePosition(index, val));
4034 break;
4035 default:
4036 UNREACHABLE();
4037 }
4038}
4039
Jamie Madille8fb6402017-02-14 17:56:40 -05004040void Context::renderbufferStorage(GLenum target,
4041 GLenum internalformat,
4042 GLsizei width,
4043 GLsizei height)
4044{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004045 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4046 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4047
Jamie Madille8fb6402017-02-14 17:56:40 -05004048 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004049 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004050}
4051
4052void Context::renderbufferStorageMultisample(GLenum target,
4053 GLsizei samples,
4054 GLenum internalformat,
4055 GLsizei width,
4056 GLsizei height)
4057{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004058 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4059 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004060
4061 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004062 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004063 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004064}
4065
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004066void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4067{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004068 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004069 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004070}
4071
JiangYizhoue18e6392017-02-20 10:32:23 +08004072void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4073{
4074 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4075 QueryFramebufferParameteriv(framebuffer, pname, params);
4076}
4077
4078void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4079{
4080 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4081 SetFramebufferParameteri(framebuffer, pname, param);
4082}
4083
Jamie Madillb3f26b92017-07-19 15:07:41 -04004084Error Context::getScratchBuffer(size_t requstedSizeBytes,
4085 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004086{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004087 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4088 {
4089 return OutOfMemory() << "Failed to allocate internal buffer.";
4090 }
4091 return NoError();
4092}
4093
4094Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4095 angle::MemoryBuffer **zeroBufferOut) const
4096{
4097 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004098 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004099 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004100 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004101 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004102}
4103
Xinghua Cao2b396592017-03-29 15:36:04 +08004104void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4105{
4106 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4107 {
4108 return;
4109 }
4110
Jamie Madill05b35b22017-10-03 09:01:44 -04004111 // TODO(jmadill): Dirty bits for compute.
Jamie Madilla59fc192017-11-02 12:57:58 -04004112 if (isRobustResourceInitEnabled())
4113 {
4114 ANGLE_CONTEXT_TRY(mGLState.clearUnclearedActiveTextures(this));
4115 }
Jamie Madill05b35b22017-10-03 09:01:44 -04004116
Jamie Madill71c88b32017-09-14 22:20:29 -04004117 handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
Xinghua Cao2b396592017-03-29 15:36:04 +08004118}
4119
JiangYizhou165361c2017-06-07 14:56:57 +08004120void Context::texStorage2D(GLenum target,
4121 GLsizei levels,
4122 GLenum internalFormat,
4123 GLsizei width,
4124 GLsizei height)
4125{
4126 Extents size(width, height, 1);
4127 Texture *texture = getTargetTexture(target);
4128 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4129}
4130
4131void Context::texStorage3D(GLenum target,
4132 GLsizei levels,
4133 GLenum internalFormat,
4134 GLsizei width,
4135 GLsizei height,
4136 GLsizei depth)
4137{
4138 Extents size(width, height, depth);
4139 Texture *texture = getTargetTexture(target);
4140 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4141}
4142
Jamie Madillc1d770e2017-04-13 17:31:24 -04004143GLenum Context::checkFramebufferStatus(GLenum target)
4144{
4145 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4146 ASSERT(framebuffer);
4147
4148 return framebuffer->checkStatus(this);
4149}
4150
4151void Context::compileShader(GLuint shader)
4152{
4153 Shader *shaderObject = GetValidShader(this, shader);
4154 if (!shaderObject)
4155 {
4156 return;
4157 }
4158 shaderObject->compile(this);
4159}
4160
4161void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4162{
4163 for (int i = 0; i < n; i++)
4164 {
4165 deleteBuffer(buffers[i]);
4166 }
4167}
4168
4169void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4170{
4171 for (int i = 0; i < n; i++)
4172 {
4173 if (framebuffers[i] != 0)
4174 {
4175 deleteFramebuffer(framebuffers[i]);
4176 }
4177 }
4178}
4179
4180void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4181{
4182 for (int i = 0; i < n; i++)
4183 {
4184 deleteRenderbuffer(renderbuffers[i]);
4185 }
4186}
4187
4188void Context::deleteTextures(GLsizei n, const GLuint *textures)
4189{
4190 for (int i = 0; i < n; i++)
4191 {
4192 if (textures[i] != 0)
4193 {
4194 deleteTexture(textures[i]);
4195 }
4196 }
4197}
4198
4199void Context::detachShader(GLuint program, GLuint shader)
4200{
4201 Program *programObject = getProgram(program);
4202 ASSERT(programObject);
4203
4204 Shader *shaderObject = getShader(shader);
4205 ASSERT(shaderObject);
4206
4207 programObject->detachShader(this, shaderObject);
4208}
4209
4210void Context::genBuffers(GLsizei n, GLuint *buffers)
4211{
4212 for (int i = 0; i < n; i++)
4213 {
4214 buffers[i] = createBuffer();
4215 }
4216}
4217
4218void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4219{
4220 for (int i = 0; i < n; i++)
4221 {
4222 framebuffers[i] = createFramebuffer();
4223 }
4224}
4225
4226void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4227{
4228 for (int i = 0; i < n; i++)
4229 {
4230 renderbuffers[i] = createRenderbuffer();
4231 }
4232}
4233
4234void Context::genTextures(GLsizei n, GLuint *textures)
4235{
4236 for (int i = 0; i < n; i++)
4237 {
4238 textures[i] = createTexture();
4239 }
4240}
4241
4242void Context::getActiveAttrib(GLuint program,
4243 GLuint index,
4244 GLsizei bufsize,
4245 GLsizei *length,
4246 GLint *size,
4247 GLenum *type,
4248 GLchar *name)
4249{
4250 Program *programObject = getProgram(program);
4251 ASSERT(programObject);
4252 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4253}
4254
4255void Context::getActiveUniform(GLuint program,
4256 GLuint index,
4257 GLsizei bufsize,
4258 GLsizei *length,
4259 GLint *size,
4260 GLenum *type,
4261 GLchar *name)
4262{
4263 Program *programObject = getProgram(program);
4264 ASSERT(programObject);
4265 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4266}
4267
4268void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4269{
4270 Program *programObject = getProgram(program);
4271 ASSERT(programObject);
4272 programObject->getAttachedShaders(maxcount, count, shaders);
4273}
4274
4275GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4276{
4277 Program *programObject = getProgram(program);
4278 ASSERT(programObject);
4279 return programObject->getAttributeLocation(name);
4280}
4281
4282void Context::getBooleanv(GLenum pname, GLboolean *params)
4283{
4284 GLenum nativeType;
4285 unsigned int numParams = 0;
4286 getQueryParameterInfo(pname, &nativeType, &numParams);
4287
4288 if (nativeType == GL_BOOL)
4289 {
4290 getBooleanvImpl(pname, params);
4291 }
4292 else
4293 {
4294 CastStateValues(this, nativeType, pname, numParams, params);
4295 }
4296}
4297
4298void Context::getFloatv(GLenum pname, GLfloat *params)
4299{
4300 GLenum nativeType;
4301 unsigned int numParams = 0;
4302 getQueryParameterInfo(pname, &nativeType, &numParams);
4303
4304 if (nativeType == GL_FLOAT)
4305 {
4306 getFloatvImpl(pname, params);
4307 }
4308 else
4309 {
4310 CastStateValues(this, nativeType, pname, numParams, params);
4311 }
4312}
4313
4314void Context::getIntegerv(GLenum pname, GLint *params)
4315{
4316 GLenum nativeType;
4317 unsigned int numParams = 0;
4318 getQueryParameterInfo(pname, &nativeType, &numParams);
4319
4320 if (nativeType == GL_INT)
4321 {
4322 getIntegervImpl(pname, params);
4323 }
4324 else
4325 {
4326 CastStateValues(this, nativeType, pname, numParams, params);
4327 }
4328}
4329
4330void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4331{
4332 Program *programObject = getProgram(program);
4333 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004334 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004335}
4336
Jamie Madillbe849e42017-05-02 15:49:00 -04004337void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004338{
4339 Program *programObject = getProgram(program);
4340 ASSERT(programObject);
4341 programObject->getInfoLog(bufsize, length, infolog);
4342}
4343
4344void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4345{
4346 Shader *shaderObject = getShader(shader);
4347 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004348 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004349}
4350
4351void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4352{
4353 Shader *shaderObject = getShader(shader);
4354 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004355 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004356}
4357
4358void Context::getShaderPrecisionFormat(GLenum shadertype,
4359 GLenum precisiontype,
4360 GLint *range,
4361 GLint *precision)
4362{
4363 // TODO(jmadill): Compute shaders.
4364
4365 switch (shadertype)
4366 {
4367 case GL_VERTEX_SHADER:
4368 switch (precisiontype)
4369 {
4370 case GL_LOW_FLOAT:
4371 mCaps.vertexLowpFloat.get(range, precision);
4372 break;
4373 case GL_MEDIUM_FLOAT:
4374 mCaps.vertexMediumpFloat.get(range, precision);
4375 break;
4376 case GL_HIGH_FLOAT:
4377 mCaps.vertexHighpFloat.get(range, precision);
4378 break;
4379
4380 case GL_LOW_INT:
4381 mCaps.vertexLowpInt.get(range, precision);
4382 break;
4383 case GL_MEDIUM_INT:
4384 mCaps.vertexMediumpInt.get(range, precision);
4385 break;
4386 case GL_HIGH_INT:
4387 mCaps.vertexHighpInt.get(range, precision);
4388 break;
4389
4390 default:
4391 UNREACHABLE();
4392 return;
4393 }
4394 break;
4395
4396 case GL_FRAGMENT_SHADER:
4397 switch (precisiontype)
4398 {
4399 case GL_LOW_FLOAT:
4400 mCaps.fragmentLowpFloat.get(range, precision);
4401 break;
4402 case GL_MEDIUM_FLOAT:
4403 mCaps.fragmentMediumpFloat.get(range, precision);
4404 break;
4405 case GL_HIGH_FLOAT:
4406 mCaps.fragmentHighpFloat.get(range, precision);
4407 break;
4408
4409 case GL_LOW_INT:
4410 mCaps.fragmentLowpInt.get(range, precision);
4411 break;
4412 case GL_MEDIUM_INT:
4413 mCaps.fragmentMediumpInt.get(range, precision);
4414 break;
4415 case GL_HIGH_INT:
4416 mCaps.fragmentHighpInt.get(range, precision);
4417 break;
4418
4419 default:
4420 UNREACHABLE();
4421 return;
4422 }
4423 break;
4424
4425 default:
4426 UNREACHABLE();
4427 return;
4428 }
4429}
4430
4431void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4432{
4433 Shader *shaderObject = getShader(shader);
4434 ASSERT(shaderObject);
4435 shaderObject->getSource(bufsize, length, source);
4436}
4437
4438void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4439{
4440 Program *programObject = getProgram(program);
4441 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004442 programObject->getUniformfv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004443}
4444
4445void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4446{
4447 Program *programObject = getProgram(program);
4448 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004449 programObject->getUniformiv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004450}
4451
4452GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4453{
4454 Program *programObject = getProgram(program);
4455 ASSERT(programObject);
4456 return programObject->getUniformLocation(name);
4457}
4458
4459GLboolean Context::isBuffer(GLuint buffer)
4460{
4461 if (buffer == 0)
4462 {
4463 return GL_FALSE;
4464 }
4465
4466 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4467}
4468
4469GLboolean Context::isEnabled(GLenum cap)
4470{
4471 return mGLState.getEnableFeature(cap);
4472}
4473
4474GLboolean Context::isFramebuffer(GLuint framebuffer)
4475{
4476 if (framebuffer == 0)
4477 {
4478 return GL_FALSE;
4479 }
4480
4481 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4482}
4483
4484GLboolean Context::isProgram(GLuint program)
4485{
4486 if (program == 0)
4487 {
4488 return GL_FALSE;
4489 }
4490
4491 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4492}
4493
4494GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4495{
4496 if (renderbuffer == 0)
4497 {
4498 return GL_FALSE;
4499 }
4500
4501 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4502}
4503
4504GLboolean Context::isShader(GLuint shader)
4505{
4506 if (shader == 0)
4507 {
4508 return GL_FALSE;
4509 }
4510
4511 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4512}
4513
4514GLboolean Context::isTexture(GLuint texture)
4515{
4516 if (texture == 0)
4517 {
4518 return GL_FALSE;
4519 }
4520
4521 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4522}
4523
4524void Context::linkProgram(GLuint program)
4525{
4526 Program *programObject = getProgram(program);
4527 ASSERT(programObject);
4528 handleError(programObject->link(this));
Martin Radev0abb7a22017-08-28 15:34:45 +03004529 mGLState.onProgramExecutableChange(programObject);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004530}
4531
4532void Context::releaseShaderCompiler()
4533{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004534 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004535}
4536
4537void Context::shaderBinary(GLsizei n,
4538 const GLuint *shaders,
4539 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004540 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004541 GLsizei length)
4542{
4543 // No binary shader formats are supported.
4544 UNIMPLEMENTED();
4545}
4546
4547void Context::shaderSource(GLuint shader,
4548 GLsizei count,
4549 const GLchar *const *string,
4550 const GLint *length)
4551{
4552 Shader *shaderObject = getShader(shader);
4553 ASSERT(shaderObject);
4554 shaderObject->setSource(count, string, length);
4555}
4556
4557void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4558{
4559 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4560}
4561
4562void Context::stencilMask(GLuint mask)
4563{
4564 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4565}
4566
4567void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4568{
4569 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4570}
4571
4572void Context::uniform1f(GLint location, GLfloat x)
4573{
4574 Program *program = mGLState.getProgram();
4575 program->setUniform1fv(location, 1, &x);
4576}
4577
4578void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4579{
4580 Program *program = mGLState.getProgram();
4581 program->setUniform1fv(location, count, v);
4582}
4583
4584void Context::uniform1i(GLint location, GLint x)
4585{
4586 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004587 if (program->setUniform1iv(location, 1, &x) == Program::SetUniformResult::SamplerChanged)
4588 {
4589 mGLState.setObjectDirty(GL_PROGRAM);
4590 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004591}
4592
4593void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4594{
4595 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004596 if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged)
4597 {
4598 mGLState.setObjectDirty(GL_PROGRAM);
4599 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004600}
4601
4602void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4603{
4604 GLfloat xy[2] = {x, y};
4605 Program *program = mGLState.getProgram();
4606 program->setUniform2fv(location, 1, xy);
4607}
4608
4609void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4610{
4611 Program *program = mGLState.getProgram();
4612 program->setUniform2fv(location, count, v);
4613}
4614
4615void Context::uniform2i(GLint location, GLint x, GLint y)
4616{
4617 GLint xy[2] = {x, y};
4618 Program *program = mGLState.getProgram();
4619 program->setUniform2iv(location, 1, xy);
4620}
4621
4622void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4623{
4624 Program *program = mGLState.getProgram();
4625 program->setUniform2iv(location, count, v);
4626}
4627
4628void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4629{
4630 GLfloat xyz[3] = {x, y, z};
4631 Program *program = mGLState.getProgram();
4632 program->setUniform3fv(location, 1, xyz);
4633}
4634
4635void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4636{
4637 Program *program = mGLState.getProgram();
4638 program->setUniform3fv(location, count, v);
4639}
4640
4641void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4642{
4643 GLint xyz[3] = {x, y, z};
4644 Program *program = mGLState.getProgram();
4645 program->setUniform3iv(location, 1, xyz);
4646}
4647
4648void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4649{
4650 Program *program = mGLState.getProgram();
4651 program->setUniform3iv(location, count, v);
4652}
4653
4654void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4655{
4656 GLfloat xyzw[4] = {x, y, z, w};
4657 Program *program = mGLState.getProgram();
4658 program->setUniform4fv(location, 1, xyzw);
4659}
4660
4661void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4662{
4663 Program *program = mGLState.getProgram();
4664 program->setUniform4fv(location, count, v);
4665}
4666
4667void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4668{
4669 GLint xyzw[4] = {x, y, z, w};
4670 Program *program = mGLState.getProgram();
4671 program->setUniform4iv(location, 1, xyzw);
4672}
4673
4674void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4675{
4676 Program *program = mGLState.getProgram();
4677 program->setUniform4iv(location, count, v);
4678}
4679
4680void Context::uniformMatrix2fv(GLint location,
4681 GLsizei count,
4682 GLboolean transpose,
4683 const GLfloat *value)
4684{
4685 Program *program = mGLState.getProgram();
4686 program->setUniformMatrix2fv(location, count, transpose, value);
4687}
4688
4689void Context::uniformMatrix3fv(GLint location,
4690 GLsizei count,
4691 GLboolean transpose,
4692 const GLfloat *value)
4693{
4694 Program *program = mGLState.getProgram();
4695 program->setUniformMatrix3fv(location, count, transpose, value);
4696}
4697
4698void Context::uniformMatrix4fv(GLint location,
4699 GLsizei count,
4700 GLboolean transpose,
4701 const GLfloat *value)
4702{
4703 Program *program = mGLState.getProgram();
4704 program->setUniformMatrix4fv(location, count, transpose, value);
4705}
4706
4707void Context::validateProgram(GLuint program)
4708{
4709 Program *programObject = getProgram(program);
4710 ASSERT(programObject);
4711 programObject->validate(mCaps);
4712}
4713
Jamie Madilld04908b2017-06-09 14:15:35 -04004714void Context::getProgramBinary(GLuint program,
4715 GLsizei bufSize,
4716 GLsizei *length,
4717 GLenum *binaryFormat,
4718 void *binary)
4719{
4720 Program *programObject = getProgram(program);
4721 ASSERT(programObject != nullptr);
4722
4723 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4724}
4725
4726void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4727{
4728 Program *programObject = getProgram(program);
4729 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004730
Jamie Madilld04908b2017-06-09 14:15:35 -04004731 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4732}
4733
Jamie Madillff325f12017-08-26 15:06:05 -04004734void Context::uniform1ui(GLint location, GLuint v0)
4735{
4736 Program *program = mGLState.getProgram();
4737 program->setUniform1uiv(location, 1, &v0);
4738}
4739
4740void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4741{
4742 Program *program = mGLState.getProgram();
4743 const GLuint xy[] = {v0, v1};
4744 program->setUniform2uiv(location, 1, xy);
4745}
4746
4747void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4748{
4749 Program *program = mGLState.getProgram();
4750 const GLuint xyz[] = {v0, v1, v2};
4751 program->setUniform3uiv(location, 1, xyz);
4752}
4753
4754void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4755{
4756 Program *program = mGLState.getProgram();
4757 const GLuint xyzw[] = {v0, v1, v2, v3};
4758 program->setUniform4uiv(location, 1, xyzw);
4759}
4760
4761void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4762{
4763 Program *program = mGLState.getProgram();
4764 program->setUniform1uiv(location, count, value);
4765}
4766void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4767{
4768 Program *program = mGLState.getProgram();
4769 program->setUniform2uiv(location, count, value);
4770}
4771
4772void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4773{
4774 Program *program = mGLState.getProgram();
4775 program->setUniform3uiv(location, count, value);
4776}
4777
4778void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4779{
4780 Program *program = mGLState.getProgram();
4781 program->setUniform4uiv(location, count, value);
4782}
4783
Jamie Madillf0e04492017-08-26 15:28:42 -04004784void Context::genQueries(GLsizei n, GLuint *ids)
4785{
4786 for (GLsizei i = 0; i < n; i++)
4787 {
4788 GLuint handle = mQueryHandleAllocator.allocate();
4789 mQueryMap.assign(handle, nullptr);
4790 ids[i] = handle;
4791 }
4792}
4793
4794void Context::deleteQueries(GLsizei n, const GLuint *ids)
4795{
4796 for (int i = 0; i < n; i++)
4797 {
4798 GLuint query = ids[i];
4799
4800 Query *queryObject = nullptr;
4801 if (mQueryMap.erase(query, &queryObject))
4802 {
4803 mQueryHandleAllocator.release(query);
4804 if (queryObject)
4805 {
4806 queryObject->release(this);
4807 }
4808 }
4809 }
4810}
4811
4812GLboolean Context::isQuery(GLuint id)
4813{
4814 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4815}
4816
Jamie Madillc8c95812017-08-26 18:40:09 -04004817void Context::uniformMatrix2x3fv(GLint location,
4818 GLsizei count,
4819 GLboolean transpose,
4820 const GLfloat *value)
4821{
4822 Program *program = mGLState.getProgram();
4823 program->setUniformMatrix2x3fv(location, count, transpose, value);
4824}
4825
4826void Context::uniformMatrix3x2fv(GLint location,
4827 GLsizei count,
4828 GLboolean transpose,
4829 const GLfloat *value)
4830{
4831 Program *program = mGLState.getProgram();
4832 program->setUniformMatrix3x2fv(location, count, transpose, value);
4833}
4834
4835void Context::uniformMatrix2x4fv(GLint location,
4836 GLsizei count,
4837 GLboolean transpose,
4838 const GLfloat *value)
4839{
4840 Program *program = mGLState.getProgram();
4841 program->setUniformMatrix2x4fv(location, count, transpose, value);
4842}
4843
4844void Context::uniformMatrix4x2fv(GLint location,
4845 GLsizei count,
4846 GLboolean transpose,
4847 const GLfloat *value)
4848{
4849 Program *program = mGLState.getProgram();
4850 program->setUniformMatrix4x2fv(location, count, transpose, value);
4851}
4852
4853void Context::uniformMatrix3x4fv(GLint location,
4854 GLsizei count,
4855 GLboolean transpose,
4856 const GLfloat *value)
4857{
4858 Program *program = mGLState.getProgram();
4859 program->setUniformMatrix3x4fv(location, count, transpose, value);
4860}
4861
4862void Context::uniformMatrix4x3fv(GLint location,
4863 GLsizei count,
4864 GLboolean transpose,
4865 const GLfloat *value)
4866{
4867 Program *program = mGLState.getProgram();
4868 program->setUniformMatrix4x3fv(location, count, transpose, value);
4869}
4870
Jamie Madilld7576732017-08-26 18:49:50 -04004871void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
4872{
4873 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4874 {
4875 GLuint vertexArray = arrays[arrayIndex];
4876
4877 if (arrays[arrayIndex] != 0)
4878 {
4879 VertexArray *vertexArrayObject = nullptr;
4880 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
4881 {
4882 if (vertexArrayObject != nullptr)
4883 {
4884 detachVertexArray(vertexArray);
4885 vertexArrayObject->onDestroy(this);
4886 }
4887
4888 mVertexArrayHandleAllocator.release(vertexArray);
4889 }
4890 }
4891 }
4892}
4893
4894void Context::genVertexArrays(GLsizei n, GLuint *arrays)
4895{
4896 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4897 {
4898 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
4899 mVertexArrayMap.assign(vertexArray, nullptr);
4900 arrays[arrayIndex] = vertexArray;
4901 }
4902}
4903
4904bool Context::isVertexArray(GLuint array)
4905{
4906 if (array == 0)
4907 {
4908 return GL_FALSE;
4909 }
4910
4911 VertexArray *vao = getVertexArray(array);
4912 return (vao != nullptr ? GL_TRUE : GL_FALSE);
4913}
4914
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04004915void Context::endTransformFeedback()
4916{
4917 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
4918 transformFeedback->end(this);
4919}
4920
4921void Context::transformFeedbackVaryings(GLuint program,
4922 GLsizei count,
4923 const GLchar *const *varyings,
4924 GLenum bufferMode)
4925{
4926 Program *programObject = getProgram(program);
4927 ASSERT(programObject);
4928 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
4929}
4930
4931void Context::getTransformFeedbackVarying(GLuint program,
4932 GLuint index,
4933 GLsizei bufSize,
4934 GLsizei *length,
4935 GLsizei *size,
4936 GLenum *type,
4937 GLchar *name)
4938{
4939 Program *programObject = getProgram(program);
4940 ASSERT(programObject);
4941 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
4942}
4943
4944void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
4945{
4946 for (int i = 0; i < n; i++)
4947 {
4948 GLuint transformFeedback = ids[i];
4949 if (transformFeedback == 0)
4950 {
4951 continue;
4952 }
4953
4954 TransformFeedback *transformFeedbackObject = nullptr;
4955 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
4956 {
4957 if (transformFeedbackObject != nullptr)
4958 {
4959 detachTransformFeedback(transformFeedback);
4960 transformFeedbackObject->release(this);
4961 }
4962
4963 mTransformFeedbackHandleAllocator.release(transformFeedback);
4964 }
4965 }
4966}
4967
4968void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
4969{
4970 for (int i = 0; i < n; i++)
4971 {
4972 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
4973 mTransformFeedbackMap.assign(transformFeedback, nullptr);
4974 ids[i] = transformFeedback;
4975 }
4976}
4977
4978bool Context::isTransformFeedback(GLuint id)
4979{
4980 if (id == 0)
4981 {
4982 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
4983 // returns FALSE
4984 return GL_FALSE;
4985 }
4986
4987 const TransformFeedback *transformFeedback = getTransformFeedback(id);
4988 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
4989}
4990
4991void Context::pauseTransformFeedback()
4992{
4993 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
4994 transformFeedback->pause();
4995}
4996
4997void Context::resumeTransformFeedback()
4998{
4999 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5000 transformFeedback->resume();
5001}
5002
Jamie Madill12e957f2017-08-26 21:42:26 -04005003void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5004{
5005 const Program *programObject = getProgram(program);
Jamie Madill54164b02017-08-28 15:17:37 -04005006 programObject->getUniformuiv(this, location, params);
Jamie Madill12e957f2017-08-26 21:42:26 -04005007}
5008
5009GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5010{
5011 const Program *programObject = getProgram(program);
5012 return programObject->getFragDataLocation(name);
5013}
5014
5015void Context::getUniformIndices(GLuint program,
5016 GLsizei uniformCount,
5017 const GLchar *const *uniformNames,
5018 GLuint *uniformIndices)
5019{
5020 const Program *programObject = getProgram(program);
5021 if (!programObject->isLinked())
5022 {
5023 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5024 {
5025 uniformIndices[uniformId] = GL_INVALID_INDEX;
5026 }
5027 }
5028 else
5029 {
5030 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5031 {
5032 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5033 }
5034 }
5035}
5036
5037void Context::getActiveUniformsiv(GLuint program,
5038 GLsizei uniformCount,
5039 const GLuint *uniformIndices,
5040 GLenum pname,
5041 GLint *params)
5042{
5043 const Program *programObject = getProgram(program);
5044 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5045 {
5046 const GLuint index = uniformIndices[uniformId];
jchen10baf5d942017-08-28 20:45:48 +08005047 params[uniformId] = GetUniformResourceProperty(programObject, index, pname);
Jamie Madill12e957f2017-08-26 21:42:26 -04005048 }
5049}
5050
5051GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5052{
5053 const Program *programObject = getProgram(program);
5054 return programObject->getUniformBlockIndex(uniformBlockName);
5055}
5056
5057void Context::getActiveUniformBlockiv(GLuint program,
5058 GLuint uniformBlockIndex,
5059 GLenum pname,
5060 GLint *params)
5061{
5062 const Program *programObject = getProgram(program);
5063 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5064}
5065
5066void Context::getActiveUniformBlockName(GLuint program,
5067 GLuint uniformBlockIndex,
5068 GLsizei bufSize,
5069 GLsizei *length,
5070 GLchar *uniformBlockName)
5071{
5072 const Program *programObject = getProgram(program);
5073 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5074}
5075
5076void Context::uniformBlockBinding(GLuint program,
5077 GLuint uniformBlockIndex,
5078 GLuint uniformBlockBinding)
5079{
5080 Program *programObject = getProgram(program);
5081 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5082}
5083
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005084GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5085{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005086 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5087 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005088
Jamie Madill70b5bb02017-08-28 13:32:37 -04005089 Sync *syncObject = getSync(syncHandle);
5090 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005091 if (error.isError())
5092 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005093 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005094 handleError(error);
5095 return nullptr;
5096 }
5097
Jamie Madill70b5bb02017-08-28 13:32:37 -04005098 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005099}
5100
5101GLboolean Context::isSync(GLsync sync)
5102{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005103 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005104}
5105
5106GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5107{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005108 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005109
5110 GLenum result = GL_WAIT_FAILED;
5111 handleError(syncObject->clientWait(flags, timeout, &result));
5112 return result;
5113}
5114
5115void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5116{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005117 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005118 handleError(syncObject->serverWait(flags, timeout));
5119}
5120
5121void Context::getInteger64v(GLenum pname, GLint64 *params)
5122{
5123 GLenum nativeType = GL_NONE;
5124 unsigned int numParams = 0;
5125 getQueryParameterInfo(pname, &nativeType, &numParams);
5126
5127 if (nativeType == GL_INT_64_ANGLEX)
5128 {
5129 getInteger64vImpl(pname, params);
5130 }
5131 else
5132 {
5133 CastStateValues(this, nativeType, pname, numParams, params);
5134 }
5135}
5136
Corentin Wallez336129f2017-10-17 15:55:40 -04005137void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params)
Jamie Madill3ef140a2017-08-26 23:11:21 -04005138{
5139 Buffer *buffer = mGLState.getTargetBuffer(target);
5140 QueryBufferParameteri64v(buffer, pname, params);
5141}
5142
5143void Context::genSamplers(GLsizei count, GLuint *samplers)
5144{
5145 for (int i = 0; i < count; i++)
5146 {
5147 samplers[i] = mState.mSamplers->createSampler();
5148 }
5149}
5150
5151void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5152{
5153 for (int i = 0; i < count; i++)
5154 {
5155 GLuint sampler = samplers[i];
5156
5157 if (mState.mSamplers->getSampler(sampler))
5158 {
5159 detachSampler(sampler);
5160 }
5161
5162 mState.mSamplers->deleteObject(this, sampler);
5163 }
5164}
5165
5166void Context::getInternalformativ(GLenum target,
5167 GLenum internalformat,
5168 GLenum pname,
5169 GLsizei bufSize,
5170 GLint *params)
5171{
5172 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5173 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5174}
5175
Jamie Madill81c2e252017-09-09 23:32:46 -04005176void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
5177{
5178 Program *programObject = getProgram(program);
5179 ASSERT(programObject);
5180 if (programObject->setUniform1iv(location, count, value) ==
5181 Program::SetUniformResult::SamplerChanged)
5182 {
5183 mGLState.setObjectDirty(GL_PROGRAM);
5184 }
5185}
5186
5187void Context::onTextureChange(const Texture *texture)
5188{
5189 // Conservatively assume all textures are dirty.
5190 // TODO(jmadill): More fine-grained update.
5191 mGLState.setObjectDirty(GL_TEXTURE);
5192}
5193
Yunchao Hea336b902017-08-02 16:05:21 +08005194void Context::genProgramPipelines(GLsizei count, GLuint *pipelines)
5195{
5196 for (int i = 0; i < count; i++)
5197 {
5198 pipelines[i] = createProgramPipeline();
5199 }
5200}
5201
5202void Context::deleteProgramPipelines(GLsizei count, const GLuint *pipelines)
5203{
5204 for (int i = 0; i < count; i++)
5205 {
5206 if (pipelines[i] != 0)
5207 {
5208 deleteProgramPipeline(pipelines[i]);
5209 }
5210 }
5211}
5212
5213GLboolean Context::isProgramPipeline(GLuint pipeline)
5214{
5215 if (pipeline == 0)
5216 {
5217 return GL_FALSE;
5218 }
5219
5220 return (getProgramPipeline(pipeline) ? GL_TRUE : GL_FALSE);
5221}
5222
Jamie Madillc29968b2016-01-20 11:17:23 -05005223} // namespace gl