blob: a0955d2b28851d85c5a975fcf231116823c6f9d8 [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"
44#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000045
Geoff Langf6db0982015-08-25 13:04:00 -040046namespace
47{
48
Jamie Madillb6664922017-07-25 12:55:04 -040049#define ANGLE_HANDLE_ERR(X) \
50 handleError(X); \
51 return;
52#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR);
53
Ian Ewell3ffd78b2016-01-22 16:09:42 -050054template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050055std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030056 GLsizei numPaths,
57 const void *paths,
58 GLuint pathBase)
59{
60 std::vector<gl::Path *> ret;
61 ret.reserve(numPaths);
62
63 const auto *nameArray = static_cast<const T *>(paths);
64
65 for (GLsizei i = 0; i < numPaths; ++i)
66 {
67 const GLuint pathName = nameArray[i] + pathBase;
68
69 ret.push_back(resourceManager.getPath(pathName));
70 }
71
72 return ret;
73}
74
Geoff Lang4ddf5af2016-12-01 14:30:44 -050075std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030076 GLsizei numPaths,
77 GLenum pathNameType,
78 const void *paths,
79 GLuint pathBase)
80{
81 switch (pathNameType)
82 {
83 case GL_UNSIGNED_BYTE:
84 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_BYTE:
87 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_SHORT:
90 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_SHORT:
93 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
94
95 case GL_UNSIGNED_INT:
96 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
97
98 case GL_INT:
99 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
100 }
101
102 UNREACHABLE();
103 return std::vector<gl::Path *>();
104}
105
106template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400107gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500108{
Geoff Lang2186c382016-10-14 10:54:54 -0400109 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500110
111 switch (pname)
112 {
113 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400114 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500115 case GL_QUERY_RESULT_AVAILABLE_EXT:
116 {
117 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400118 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500119 if (!error.isError())
120 {
Geoff Lang2186c382016-10-14 10:54:54 -0400121 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500122 }
123 return error;
124 }
125 default:
126 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500127 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500128 }
129}
130
Geoff Langf6db0982015-08-25 13:04:00 -0400131void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
132{
Geoff Lang1a683462015-09-29 15:09:59 -0400133 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400134 {
135 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
136 tfBufferIndex++)
137 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400138 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400139 transformFeedback->getIndexedBuffer(tfBufferIndex);
140 if (buffer.get() != nullptr)
141 {
142 buffer->onTransformFeedback();
143 }
144 }
145 }
146}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500147
148// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300149EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500150{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400151 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500152}
153
Martin Radev1be913c2016-07-11 17:59:16 +0300154EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
155{
156 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
157}
158
Geoff Langeb66a6e2016-10-31 13:06:12 -0400159gl::Version GetClientVersion(const egl::AttributeMap &attribs)
160{
161 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
162}
163
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500164GLenum GetResetStrategy(const egl::AttributeMap &attribs)
165{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400166 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
167 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500168 switch (attrib)
169 {
170 case EGL_NO_RESET_NOTIFICATION:
171 return GL_NO_RESET_NOTIFICATION_EXT;
172 case EGL_LOSE_CONTEXT_ON_RESET:
173 return GL_LOSE_CONTEXT_ON_RESET_EXT;
174 default:
175 UNREACHABLE();
176 return GL_NONE;
177 }
178}
179
180bool GetRobustAccess(const egl::AttributeMap &attribs)
181{
Geoff Lang077f20a2016-11-01 10:08:02 -0400182 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
183 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
184 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetDebug(const egl::AttributeMap &attribs)
188{
Geoff Lang077f20a2016-11-01 10:08:02 -0400189 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
190 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500191}
192
193bool GetNoError(const egl::AttributeMap &attribs)
194{
195 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
196}
197
Geoff Langc287ea62016-09-16 14:46:51 -0400198bool GetWebGLContext(const egl::AttributeMap &attribs)
199{
200 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
201}
202
Geoff Langf41a7152016-09-19 15:11:17 -0400203bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
204{
205 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
206}
207
Geoff Langfeb8c682017-02-13 16:07:35 -0500208bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
209{
210 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
211}
212
Martin Radev9d901792016-07-15 15:58:58 +0300213std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
214{
215 std::string labelName;
216 if (label != nullptr)
217 {
218 size_t labelLength = length < 0 ? strlen(label) : length;
219 labelName = std::string(label, labelLength);
220 }
221 return labelName;
222}
223
224void GetObjectLabelBase(const std::string &objectLabel,
225 GLsizei bufSize,
226 GLsizei *length,
227 GLchar *label)
228{
229 size_t writeLength = objectLabel.length();
230 if (label != nullptr && bufSize > 0)
231 {
232 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
233 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
234 label[writeLength] = '\0';
235 }
236
237 if (length != nullptr)
238 {
239 *length = static_cast<GLsizei>(writeLength);
240 }
241}
242
Geoff Langf6db0982015-08-25 13:04:00 -0400243} // anonymous namespace
244
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000245namespace gl
246{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000247
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400248Context::Context(rx::EGLImplFactory *implFactory,
249 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400250 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500251 TextureManager *shareTextures,
Jamie Madill32447362017-06-28 14:53:52 -0400252 MemoryProgramCache *memoryProgramCache,
Corentin Wallezc295e512017-01-27 17:47:50 -0500253 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400254 const egl::DisplayExtensions &displayExtensions,
255 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300256
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500257 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500258 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500259 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700260 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500261 mCaps,
262 mTextureCaps,
263 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500264 mLimitations,
265 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700266 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400267 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400268 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500269 mClientType(EGL_OPENGL_ES_API),
270 mHasBeenCurrent(false),
271 mContextLost(false),
272 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700273 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500274 mResetStrategy(GetResetStrategy(attribs)),
275 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400276 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
277 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500278 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500279 mWebGLContext(GetWebGLContext(attribs)),
Jamie Madill32447362017-06-28 14:53:52 -0400280 mMemoryProgramCache(memoryProgramCache),
Jamie Madillb3f26b92017-07-19 15:07:41 -0400281 mScratchBuffer(1000u),
282 mZeroFilledBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000283{
Jamie Madill14bbb3f2017-09-12 15:23:01 -0400284 mImplementation->setMemoryProgramCache(memoryProgramCache);
285
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500286 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700287 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400288
Jamie Madill4928b7c2017-06-20 12:57:39 -0400289 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400290 GetClientArraysEnabled(attribs), robustResourceInit,
291 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100292
Shannon Woods53a94a82014-06-24 15:20:36 -0400293 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400294
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000295 // [OpenGL ES 2.0.24] section 3.7 page 83:
296 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
297 // and cube map texture state vectors respectively associated with them.
298 // In order that access to these initial textures not be lost, they are treated as texture
299 // objects all of whose names are 0.
300
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400301 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400302 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500303
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400304 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400305 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400306
Geoff Langeb66a6e2016-10-31 13:06:12 -0400307 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400308 {
309 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400310 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400311 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400313 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400314 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400315 }
Geoff Lang3b573612016-10-31 14:08:10 -0400316 if (getClientVersion() >= Version(3, 1))
317 {
318 Texture *zeroTexture2DMultisample =
319 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400320 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800321
322 bindGenericAtomicCounterBuffer(0);
323 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
324 {
325 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
326 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800327
328 bindGenericShaderStorageBuffer(0);
329 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
330 {
331 bindIndexedShaderStorageBuffer(0, i, 0, 0);
332 }
Geoff Lang3b573612016-10-31 14:08:10 -0400333 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000334
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400335 if (mExtensions.textureRectangle)
336 {
337 Texture *zeroTextureRectangle =
338 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
339 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
340 }
341
Ian Ewellbda75592016-04-18 17:25:54 -0400342 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
343 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400344 Texture *zeroTextureExternal =
345 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400346 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400347 }
348
Jamie Madill4928b7c2017-06-20 12:57:39 -0400349 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500350
Jamie Madill57a89722013-07-02 11:57:03 -0400351 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000352 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800353 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000354 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400355
Jamie Madill01a80ee2016-11-07 12:06:18 -0500356 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000357
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000358 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500359 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000360 {
361 bindIndexedUniformBuffer(0, i, 0, -1);
362 }
363
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000364 bindCopyReadBuffer(0);
365 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000366 bindPixelPackBuffer(0);
367 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000368
Geoff Langeb66a6e2016-10-31 13:06:12 -0400369 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400370 {
371 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
372 // In the initial state, a default transform feedback object is bound and treated as
373 // a transform feedback object with a name of zero. That object is bound any time
374 // BindTransformFeedback is called with id of zero
Jamie Madillf0dcb8b2017-08-26 19:05:13 -0400375 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Geoff Lang1a683462015-09-29 15:09:59 -0400376 }
Geoff Langc8058452014-02-03 12:04:11 -0500377
Jamie Madillad9f24e2016-02-12 09:27:24 -0500378 // Initialize dirty bit masks
379 // TODO(jmadill): additional ES3 state
380 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
381 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
382 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
383 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
384 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
385 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400386 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500387 // No dirty objects.
388
389 // Readpixels uses the pack state and read FBO
390 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
391 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
392 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
393 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
394 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400395 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500396 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
397
398 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
399 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
400 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
401 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
402 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
403 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
404 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
405 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
406 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
407 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
408 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
409 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
410
411 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
412 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700413 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500414 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
415 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400416
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400417 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418}
419
Jamie Madill4928b7c2017-06-20 12:57:39 -0400420egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421{
Corentin Wallez80b24112015-08-25 16:41:57 -0400422 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400424 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000425 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400426 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427
Corentin Wallez80b24112015-08-25 16:41:57 -0400428 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400430 if (query.second != nullptr)
431 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400432 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400433 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000434 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400435 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000436
Corentin Wallez80b24112015-08-25 16:41:57 -0400437 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400438 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400439 if (vertexArray.second)
440 {
441 vertexArray.second->onDestroy(this);
442 }
Jamie Madill57a89722013-07-02 11:57:03 -0400443 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400444 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400445
Corentin Wallez80b24112015-08-25 16:41:57 -0400446 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500447 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500448 if (transformFeedback.second != nullptr)
449 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500450 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500451 }
Geoff Langc8058452014-02-03 12:04:11 -0500452 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400453 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500454
Jamie Madilldedd7b92014-11-05 16:30:36 -0500455 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400456 {
Jamie Madill71c88b32017-09-14 22:20:29 -0400457 ANGLE_TRY(zeroTexture.second->onDestroy(this));
Jamie Madill4928b7c2017-06-20 12:57:39 -0400458 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400459 }
460 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000461
Corentin Wallezccab69d2017-01-27 16:57:15 -0500462 SafeDelete(mSurfacelessFramebuffer);
463
Jamie Madill4928b7c2017-06-20 12:57:39 -0400464 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400465 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500466
Jamie Madill4928b7c2017-06-20 12:57:39 -0400467 mGLState.reset(this);
468
Jamie Madill6c1f6712017-02-14 19:08:04 -0500469 mState.mBuffers->release(this);
470 mState.mShaderPrograms->release(this);
471 mState.mTextures->release(this);
472 mState.mRenderbuffers->release(this);
473 mState.mSamplers->release(this);
Jamie Madill70b5bb02017-08-28 13:32:37 -0400474 mState.mSyncs->release(this);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500475 mState.mPaths->release(this);
476 mState.mFramebuffers->release(this);
Yunchao Hea336b902017-08-02 16:05:21 +0800477 mState.mPipelines->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400478
479 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000480}
481
Jamie Madill70ee0f62017-02-06 16:04:20 -0500482Context::~Context()
483{
484}
485
Jamie Madill4928b7c2017-06-20 12:57:39 -0400486egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000487{
Jamie Madill61e16b42017-06-19 11:13:23 -0400488 mCurrentDisplay = display;
489
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000490 if (!mHasBeenCurrent)
491 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000492 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500493 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400494 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000495
Corentin Wallezc295e512017-01-27 17:47:50 -0500496 int width = 0;
497 int height = 0;
498 if (surface != nullptr)
499 {
500 width = surface->getWidth();
501 height = surface->getHeight();
502 }
503
504 mGLState.setViewportParams(0, 0, width, height);
505 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000506
507 mHasBeenCurrent = true;
508 }
509
Jamie Madill1b94d432015-08-07 13:23:23 -0400510 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700511 mGLState.setAllDirtyBits();
Jamie Madill81c2e252017-09-09 23:32:46 -0400512 mGLState.setAllDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -0400513
Jamie Madill4928b7c2017-06-20 12:57:39 -0400514 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500515
516 Framebuffer *newDefault = nullptr;
517 if (surface != nullptr)
518 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400519 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500520 mCurrentSurface = surface;
521 newDefault = surface->getDefaultFramebuffer();
522 }
523 else
524 {
525 if (mSurfacelessFramebuffer == nullptr)
526 {
527 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
528 }
529
530 newDefault = mSurfacelessFramebuffer;
531 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000532
Corentin Wallez37c39792015-08-20 14:19:46 -0400533 // Update default framebuffer, the binding of the previous default
534 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400535 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700536 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400537 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700538 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400539 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700540 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400541 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700542 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400543 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500544 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400545 }
Ian Ewell292f0052016-02-04 10:37:32 -0500546
547 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400548 mImplementation->onMakeCurrent(this);
549 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000550}
551
Jamie Madill4928b7c2017-06-20 12:57:39 -0400552egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400553{
Corentin Wallez37c39792015-08-20 14:19:46 -0400554 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500555 Framebuffer *currentDefault = nullptr;
556 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400557 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500558 currentDefault = mCurrentSurface->getDefaultFramebuffer();
559 }
560 else if (mSurfacelessFramebuffer != nullptr)
561 {
562 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400563 }
564
Corentin Wallezc295e512017-01-27 17:47:50 -0500565 if (mGLState.getReadFramebuffer() == currentDefault)
566 {
567 mGLState.setReadFramebufferBinding(nullptr);
568 }
569 if (mGLState.getDrawFramebuffer() == currentDefault)
570 {
571 mGLState.setDrawFramebufferBinding(nullptr);
572 }
573 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
574
575 if (mCurrentSurface)
576 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400577 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500578 mCurrentSurface = nullptr;
579 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400580
581 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400582}
583
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000584GLuint Context::createBuffer()
585{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500586 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587}
588
589GLuint Context::createProgram()
590{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500591 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592}
593
594GLuint Context::createShader(GLenum type)
595{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500596 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597}
598
599GLuint Context::createTexture()
600{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500601 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000602}
603
604GLuint Context::createRenderbuffer()
605{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500606 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000607}
608
Sami Väisänene45e53b2016-05-25 10:36:04 +0300609GLuint Context::createPaths(GLsizei range)
610{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500611 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300612 if (resultOrError.isError())
613 {
614 handleError(resultOrError.getError());
615 return 0;
616 }
617 return resultOrError.getResult();
618}
619
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620// Returns an unused framebuffer name
621GLuint Context::createFramebuffer()
622{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500623 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000624}
625
Jamie Madill33dc8432013-07-26 11:55:05 -0400626GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000627{
Jamie Madill33dc8432013-07-26 11:55:05 -0400628 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400629 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630 return handle;
631}
632
Yunchao Hea336b902017-08-02 16:05:21 +0800633GLuint Context::createProgramPipeline()
634{
635 return mState.mPipelines->createProgramPipeline();
636}
637
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000638void Context::deleteBuffer(GLuint buffer)
639{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500640 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641 {
642 detachBuffer(buffer);
643 }
Jamie Madill893ab082014-05-16 16:56:10 -0400644
Jamie Madill6c1f6712017-02-14 19:08:04 -0500645 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000646}
647
648void Context::deleteShader(GLuint shader)
649{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500650 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651}
652
653void Context::deleteProgram(GLuint program)
654{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500655 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656}
657
658void Context::deleteTexture(GLuint texture)
659{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500660 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000661 {
662 detachTexture(texture);
663 }
664
Jamie Madill6c1f6712017-02-14 19:08:04 -0500665 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000666}
667
668void Context::deleteRenderbuffer(GLuint renderbuffer)
669{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500670 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000671 {
672 detachRenderbuffer(renderbuffer);
673 }
Jamie Madill893ab082014-05-16 16:56:10 -0400674
Jamie Madill6c1f6712017-02-14 19:08:04 -0500675 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000676}
677
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400678void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400679{
680 // The spec specifies the underlying Fence object is not deleted until all current
681 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
682 // and since our API is currently designed for being called from a single thread, we can delete
683 // the fence immediately.
Jamie Madill70b5bb02017-08-28 13:32:37 -0400684 mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400685}
686
Yunchao Hea336b902017-08-02 16:05:21 +0800687void Context::deleteProgramPipeline(GLuint pipeline)
688{
689 if (mState.mPipelines->getProgramPipeline(pipeline))
690 {
691 detachProgramPipeline(pipeline);
692 }
693
694 mState.mPipelines->deleteObject(this, pipeline);
695}
696
Sami Väisänene45e53b2016-05-25 10:36:04 +0300697void Context::deletePaths(GLuint first, GLsizei range)
698{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500699 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300700}
701
702bool Context::hasPathData(GLuint path) const
703{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500704 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300705 if (pathObj == nullptr)
706 return false;
707
708 return pathObj->hasPathData();
709}
710
711bool Context::hasPath(GLuint path) const
712{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500713 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300714}
715
716void Context::setPathCommands(GLuint path,
717 GLsizei numCommands,
718 const GLubyte *commands,
719 GLsizei numCoords,
720 GLenum coordType,
721 const void *coords)
722{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500723 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300724
725 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
726}
727
728void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
729{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500730 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300731
732 switch (pname)
733 {
734 case GL_PATH_STROKE_WIDTH_CHROMIUM:
735 pathObj->setStrokeWidth(value);
736 break;
737 case GL_PATH_END_CAPS_CHROMIUM:
738 pathObj->setEndCaps(static_cast<GLenum>(value));
739 break;
740 case GL_PATH_JOIN_STYLE_CHROMIUM:
741 pathObj->setJoinStyle(static_cast<GLenum>(value));
742 break;
743 case GL_PATH_MITER_LIMIT_CHROMIUM:
744 pathObj->setMiterLimit(value);
745 break;
746 case GL_PATH_STROKE_BOUND_CHROMIUM:
747 pathObj->setStrokeBound(value);
748 break;
749 default:
750 UNREACHABLE();
751 break;
752 }
753}
754
755void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
756{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500757 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300758
759 switch (pname)
760 {
761 case GL_PATH_STROKE_WIDTH_CHROMIUM:
762 *value = pathObj->getStrokeWidth();
763 break;
764 case GL_PATH_END_CAPS_CHROMIUM:
765 *value = static_cast<GLfloat>(pathObj->getEndCaps());
766 break;
767 case GL_PATH_JOIN_STYLE_CHROMIUM:
768 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
769 break;
770 case GL_PATH_MITER_LIMIT_CHROMIUM:
771 *value = pathObj->getMiterLimit();
772 break;
773 case GL_PATH_STROKE_BOUND_CHROMIUM:
774 *value = pathObj->getStrokeBound();
775 break;
776 default:
777 UNREACHABLE();
778 break;
779 }
780}
781
782void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
783{
784 mGLState.setPathStencilFunc(func, ref, mask);
785}
786
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000787void Context::deleteFramebuffer(GLuint framebuffer)
788{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500789 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000790 {
791 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000792 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500793
Jamie Madill6c1f6712017-02-14 19:08:04 -0500794 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795}
796
Jamie Madill33dc8432013-07-26 11:55:05 -0400797void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798{
Jamie Madill96a483b2017-06-27 16:49:21 -0400799 FenceNV *fenceObject = nullptr;
800 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400802 mFenceNVHandleAllocator.release(fence);
803 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000804 }
805}
806
Geoff Lang70d0f492015-12-10 17:45:46 -0500807Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000808{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500809 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810}
811
Jamie Madill570f7c82014-07-03 10:38:54 -0400812Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500814 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815}
816
Geoff Lang70d0f492015-12-10 17:45:46 -0500817Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000818{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500819 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820}
821
Jamie Madill70b5bb02017-08-28 13:32:37 -0400822Sync *Context::getSync(GLsync handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400823{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400824 return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400825}
826
Jamie Madill57a89722013-07-02 11:57:03 -0400827VertexArray *Context::getVertexArray(GLuint handle) const
828{
Jamie Madill96a483b2017-06-27 16:49:21 -0400829 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400830}
831
Jamie Madilldc356042013-07-19 16:36:57 -0400832Sampler *Context::getSampler(GLuint handle) const
833{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500834 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400835}
836
Geoff Langc8058452014-02-03 12:04:11 -0500837TransformFeedback *Context::getTransformFeedback(GLuint handle) const
838{
Jamie Madill96a483b2017-06-27 16:49:21 -0400839 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500840}
841
Yunchao Hea336b902017-08-02 16:05:21 +0800842ProgramPipeline *Context::getProgramPipeline(GLuint handle) const
843{
844 return mState.mPipelines->getProgramPipeline(handle);
845}
846
Geoff Lang70d0f492015-12-10 17:45:46 -0500847LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
848{
849 switch (identifier)
850 {
851 case GL_BUFFER:
852 return getBuffer(name);
853 case GL_SHADER:
854 return getShader(name);
855 case GL_PROGRAM:
856 return getProgram(name);
857 case GL_VERTEX_ARRAY:
858 return getVertexArray(name);
859 case GL_QUERY:
860 return getQuery(name);
861 case GL_TRANSFORM_FEEDBACK:
862 return getTransformFeedback(name);
863 case GL_SAMPLER:
864 return getSampler(name);
865 case GL_TEXTURE:
866 return getTexture(name);
867 case GL_RENDERBUFFER:
868 return getRenderbuffer(name);
869 case GL_FRAMEBUFFER:
870 return getFramebuffer(name);
871 default:
872 UNREACHABLE();
873 return nullptr;
874 }
875}
876
877LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
878{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400879 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
Geoff Lang70d0f492015-12-10 17:45:46 -0500880}
881
Martin Radev9d901792016-07-15 15:58:58 +0300882void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
883{
884 LabeledObject *object = getLabeledObject(identifier, name);
885 ASSERT(object != nullptr);
886
887 std::string labelName = GetObjectLabelFromPointer(length, label);
888 object->setLabel(labelName);
Jamie Madill8693bdb2017-09-02 15:32:14 -0400889
890 // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
891 // specified object is active until we do this.
892 mGLState.setObjectDirty(identifier);
Martin Radev9d901792016-07-15 15:58:58 +0300893}
894
895void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
896{
897 LabeledObject *object = getLabeledObjectFromPtr(ptr);
898 ASSERT(object != nullptr);
899
900 std::string labelName = GetObjectLabelFromPointer(length, label);
901 object->setLabel(labelName);
902}
903
904void Context::getObjectLabel(GLenum identifier,
905 GLuint name,
906 GLsizei bufSize,
907 GLsizei *length,
908 GLchar *label) const
909{
910 LabeledObject *object = getLabeledObject(identifier, name);
911 ASSERT(object != nullptr);
912
913 const std::string &objectLabel = object->getLabel();
914 GetObjectLabelBase(objectLabel, bufSize, length, label);
915}
916
917void Context::getObjectPtrLabel(const void *ptr,
918 GLsizei bufSize,
919 GLsizei *length,
920 GLchar *label) const
921{
922 LabeledObject *object = getLabeledObjectFromPtr(ptr);
923 ASSERT(object != nullptr);
924
925 const std::string &objectLabel = object->getLabel();
926 GetObjectLabelBase(objectLabel, bufSize, length, label);
927}
928
Jamie Madilldc356042013-07-19 16:36:57 -0400929bool Context::isSampler(GLuint samplerName) const
930{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500931 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400932}
933
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500934void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000935{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500936 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400937 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000938}
939
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800940void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
941{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500942 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400943 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800944}
945
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500946void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000947{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500948 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400949 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950}
951
Jamie Madilldedd7b92014-11-05 16:30:36 -0500952void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500954 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955
Jamie Madilldedd7b92014-11-05 16:30:36 -0500956 if (handle == 0)
957 {
958 texture = mZeroTextures[target].get();
959 }
960 else
961 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500962 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500963 }
964
965 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400966 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000967}
968
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500969void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000970{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500971 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
972 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700973 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974}
975
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500976void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500978 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
979 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700980 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981}
982
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500983void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400984{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500985 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700986 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400987}
988
Shao80957d92017-02-20 21:25:59 +0800989void Context::bindVertexBuffer(GLuint bindingIndex,
990 GLuint bufferHandle,
991 GLintptr offset,
992 GLsizei stride)
993{
994 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400995 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +0800996}
997
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500998void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400999{
Geoff Lang76b10c92014-09-05 16:28:14 -04001000 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001001 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001002 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001003 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001004}
1005
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001006void Context::bindImageTexture(GLuint unit,
1007 GLuint texture,
1008 GLint level,
1009 GLboolean layered,
1010 GLint layer,
1011 GLenum access,
1012 GLenum format)
1013{
1014 Texture *tex = mState.mTextures->getTexture(texture);
1015 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1016}
1017
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001018void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001019{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001020 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001021 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001022}
1023
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1025 GLuint index,
1026 GLintptr offset,
1027 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001028{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001029 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001030 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001031}
1032
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001033void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001034{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001035 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001036 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001037}
1038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1040 GLuint index,
1041 GLintptr offset,
1042 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001043{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001044 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001045 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001046}
1047
Jiajia Qin6eafb042016-12-27 17:04:07 +08001048void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1049{
1050 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001051 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001052}
1053
1054void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1055 GLuint index,
1056 GLintptr offset,
1057 GLsizeiptr size)
1058{
1059 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001060 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001061}
1062
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001063void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1064{
1065 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001066 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001067}
1068
1069void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1070 GLuint index,
1071 GLintptr offset,
1072 GLsizeiptr size)
1073{
1074 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001075 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001076}
1077
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001078void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001079{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001080 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001081 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001082}
1083
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001084void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001085{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001086 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001087 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001088}
1089
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001090void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001091{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001092 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001093 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001094}
1095
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001096void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001097{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001098 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001099 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001100}
1101
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001102void Context::useProgram(GLuint program)
1103{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001104 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001105}
1106
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001107void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001108{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001109 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001110 TransformFeedback *transformFeedback =
1111 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001112 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001113}
1114
Yunchao Hea336b902017-08-02 16:05:21 +08001115void Context::bindProgramPipeline(GLuint pipelineHandle)
1116{
1117 ProgramPipeline *pipeline =
1118 mState.mPipelines->checkProgramPipelineAllocation(mImplementation.get(), pipelineHandle);
1119 mGLState.setProgramPipelineBinding(this, pipeline);
1120}
1121
Jamie Madillf0e04492017-08-26 15:28:42 -04001122void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001123{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001124 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001125 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001126
Geoff Lang5aad9672014-09-08 11:10:42 -04001127 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001128 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001129
1130 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001131 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001132}
1133
Jamie Madillf0e04492017-08-26 15:28:42 -04001134void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001135{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001136 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001137 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001138
Jamie Madillf0e04492017-08-26 15:28:42 -04001139 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001140
Geoff Lang5aad9672014-09-08 11:10:42 -04001141 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001142 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001143}
1144
Jamie Madillf0e04492017-08-26 15:28:42 -04001145void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001146{
1147 ASSERT(target == GL_TIMESTAMP_EXT);
1148
1149 Query *queryObject = getQuery(id, true, target);
1150 ASSERT(queryObject);
1151
Jamie Madillf0e04492017-08-26 15:28:42 -04001152 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001153}
1154
1155void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1156{
1157 switch (pname)
1158 {
1159 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001160 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001161 break;
1162 case GL_QUERY_COUNTER_BITS_EXT:
1163 switch (target)
1164 {
1165 case GL_TIME_ELAPSED_EXT:
1166 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1167 break;
1168 case GL_TIMESTAMP_EXT:
1169 params[0] = getExtensions().queryCounterBitsTimestamp;
1170 break;
1171 default:
1172 UNREACHABLE();
1173 params[0] = 0;
1174 break;
1175 }
1176 break;
1177 default:
1178 UNREACHABLE();
1179 return;
1180 }
1181}
1182
Geoff Lang2186c382016-10-14 10:54:54 -04001183void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001184{
Geoff Lang2186c382016-10-14 10:54:54 -04001185 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001186}
1187
Geoff Lang2186c382016-10-14 10:54:54 -04001188void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001189{
Geoff Lang2186c382016-10-14 10:54:54 -04001190 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001191}
1192
Geoff Lang2186c382016-10-14 10:54:54 -04001193void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001194{
Geoff Lang2186c382016-10-14 10:54:54 -04001195 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001196}
1197
Geoff Lang2186c382016-10-14 10:54:54 -04001198void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001199{
Geoff Lang2186c382016-10-14 10:54:54 -04001200 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001201}
1202
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001203Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001204{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001205 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206}
1207
Jamie Madill2f348d22017-06-05 10:50:59 -04001208FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001209{
Jamie Madill96a483b2017-06-27 16:49:21 -04001210 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001211}
1212
Jamie Madill2f348d22017-06-05 10:50:59 -04001213Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001214{
Jamie Madill96a483b2017-06-27 16:49:21 -04001215 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001217 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001219
1220 Query *query = mQueryMap.query(handle);
1221 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001222 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001223 query = new Query(mImplementation->createQuery(type), handle);
1224 query->addRef();
1225 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001227 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001228}
1229
Geoff Lang70d0f492015-12-10 17:45:46 -05001230Query *Context::getQuery(GLuint handle) const
1231{
Jamie Madill96a483b2017-06-27 16:49:21 -04001232 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001233}
1234
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001235Texture *Context::getTargetTexture(GLenum target) const
1236{
Ian Ewellbda75592016-04-18 17:25:54 -04001237 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001238 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001239}
1240
Geoff Lang76b10c92014-09-05 16:28:14 -04001241Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001243 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244}
1245
Geoff Lang492a7e42014-11-05 13:27:06 -05001246Compiler *Context::getCompiler() const
1247{
Jamie Madill2f348d22017-06-05 10:50:59 -04001248 if (mCompiler.get() == nullptr)
1249 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001250 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001251 }
1252 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001253}
1254
Jamie Madillc1d770e2017-04-13 17:31:24 -04001255void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001256{
1257 switch (pname)
1258 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001259 case GL_SHADER_COMPILER:
1260 *params = GL_TRUE;
1261 break;
1262 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1263 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1264 break;
1265 default:
1266 mGLState.getBooleanv(pname, params);
1267 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001269}
1270
Jamie Madillc1d770e2017-04-13 17:31:24 -04001271void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272{
Shannon Woods53a94a82014-06-24 15:20:36 -04001273 // Queries about context capabilities and maximums are answered by Context.
1274 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275 switch (pname)
1276 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001277 case GL_ALIASED_LINE_WIDTH_RANGE:
1278 params[0] = mCaps.minAliasedLineWidth;
1279 params[1] = mCaps.maxAliasedLineWidth;
1280 break;
1281 case GL_ALIASED_POINT_SIZE_RANGE:
1282 params[0] = mCaps.minAliasedPointSize;
1283 params[1] = mCaps.maxAliasedPointSize;
1284 break;
1285 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1286 ASSERT(mExtensions.textureFilterAnisotropic);
1287 *params = mExtensions.maxTextureAnisotropy;
1288 break;
1289 case GL_MAX_TEXTURE_LOD_BIAS:
1290 *params = mCaps.maxLODBias;
1291 break;
1292
1293 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1294 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1295 {
1296 ASSERT(mExtensions.pathRendering);
1297 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1298 memcpy(params, m, 16 * sizeof(GLfloat));
1299 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001300 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001301
Jamie Madill231c7f52017-04-26 13:45:37 -04001302 default:
1303 mGLState.getFloatv(pname, params);
1304 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001305 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001306}
1307
Jamie Madillc1d770e2017-04-13 17:31:24 -04001308void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001309{
Shannon Woods53a94a82014-06-24 15:20:36 -04001310 // Queries about context capabilities and maximums are answered by Context.
1311 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001312
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001313 switch (pname)
1314 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001315 case GL_MAX_VERTEX_ATTRIBS:
1316 *params = mCaps.maxVertexAttributes;
1317 break;
1318 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1319 *params = mCaps.maxVertexUniformVectors;
1320 break;
1321 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1322 *params = mCaps.maxVertexUniformComponents;
1323 break;
1324 case GL_MAX_VARYING_VECTORS:
1325 *params = mCaps.maxVaryingVectors;
1326 break;
1327 case GL_MAX_VARYING_COMPONENTS:
1328 *params = mCaps.maxVertexOutputComponents;
1329 break;
1330 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1331 *params = mCaps.maxCombinedTextureImageUnits;
1332 break;
1333 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1334 *params = mCaps.maxVertexTextureImageUnits;
1335 break;
1336 case GL_MAX_TEXTURE_IMAGE_UNITS:
1337 *params = mCaps.maxTextureImageUnits;
1338 break;
1339 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1340 *params = mCaps.maxFragmentUniformVectors;
1341 break;
1342 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1343 *params = mCaps.maxFragmentUniformComponents;
1344 break;
1345 case GL_MAX_RENDERBUFFER_SIZE:
1346 *params = mCaps.maxRenderbufferSize;
1347 break;
1348 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1349 *params = mCaps.maxColorAttachments;
1350 break;
1351 case GL_MAX_DRAW_BUFFERS_EXT:
1352 *params = mCaps.maxDrawBuffers;
1353 break;
1354 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1355 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1356 case GL_SUBPIXEL_BITS:
1357 *params = 4;
1358 break;
1359 case GL_MAX_TEXTURE_SIZE:
1360 *params = mCaps.max2DTextureSize;
1361 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001362 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1363 *params = mCaps.maxRectangleTextureSize;
1364 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001365 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1366 *params = mCaps.maxCubeMapTextureSize;
1367 break;
1368 case GL_MAX_3D_TEXTURE_SIZE:
1369 *params = mCaps.max3DTextureSize;
1370 break;
1371 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1372 *params = mCaps.maxArrayTextureLayers;
1373 break;
1374 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1375 *params = mCaps.uniformBufferOffsetAlignment;
1376 break;
1377 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1378 *params = mCaps.maxUniformBufferBindings;
1379 break;
1380 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1381 *params = mCaps.maxVertexUniformBlocks;
1382 break;
1383 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1384 *params = mCaps.maxFragmentUniformBlocks;
1385 break;
1386 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1387 *params = mCaps.maxCombinedTextureImageUnits;
1388 break;
1389 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1390 *params = mCaps.maxVertexOutputComponents;
1391 break;
1392 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1393 *params = mCaps.maxFragmentInputComponents;
1394 break;
1395 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1396 *params = mCaps.minProgramTexelOffset;
1397 break;
1398 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1399 *params = mCaps.maxProgramTexelOffset;
1400 break;
1401 case GL_MAJOR_VERSION:
1402 *params = getClientVersion().major;
1403 break;
1404 case GL_MINOR_VERSION:
1405 *params = getClientVersion().minor;
1406 break;
1407 case GL_MAX_ELEMENTS_INDICES:
1408 *params = mCaps.maxElementsIndices;
1409 break;
1410 case GL_MAX_ELEMENTS_VERTICES:
1411 *params = mCaps.maxElementsVertices;
1412 break;
1413 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1414 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1415 break;
1416 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1417 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1418 break;
1419 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1420 *params = mCaps.maxTransformFeedbackSeparateComponents;
1421 break;
1422 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1423 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1424 break;
1425 case GL_MAX_SAMPLES_ANGLE:
1426 *params = mCaps.maxSamples;
1427 break;
1428 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001429 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001430 params[0] = mCaps.maxViewportWidth;
1431 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001432 }
1433 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001434 case GL_COMPRESSED_TEXTURE_FORMATS:
1435 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1436 params);
1437 break;
1438 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1439 *params = mResetStrategy;
1440 break;
1441 case GL_NUM_SHADER_BINARY_FORMATS:
1442 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1443 break;
1444 case GL_SHADER_BINARY_FORMATS:
1445 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1446 break;
1447 case GL_NUM_PROGRAM_BINARY_FORMATS:
1448 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1449 break;
1450 case GL_PROGRAM_BINARY_FORMATS:
1451 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1452 break;
1453 case GL_NUM_EXTENSIONS:
1454 *params = static_cast<GLint>(mExtensionStrings.size());
1455 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001456
Jamie Madill231c7f52017-04-26 13:45:37 -04001457 // GL_KHR_debug
1458 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1459 *params = mExtensions.maxDebugMessageLength;
1460 break;
1461 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1462 *params = mExtensions.maxDebugLoggedMessages;
1463 break;
1464 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1465 *params = mExtensions.maxDebugGroupStackDepth;
1466 break;
1467 case GL_MAX_LABEL_LENGTH:
1468 *params = mExtensions.maxLabelLength;
1469 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001470
Martin Radeve5285d22017-07-14 16:23:53 +03001471 // GL_ANGLE_multiview
1472 case GL_MAX_VIEWS_ANGLE:
1473 *params = mExtensions.maxViews;
1474 break;
1475
Jamie Madill231c7f52017-04-26 13:45:37 -04001476 // GL_EXT_disjoint_timer_query
1477 case GL_GPU_DISJOINT_EXT:
1478 *params = mImplementation->getGPUDisjoint();
1479 break;
1480 case GL_MAX_FRAMEBUFFER_WIDTH:
1481 *params = mCaps.maxFramebufferWidth;
1482 break;
1483 case GL_MAX_FRAMEBUFFER_HEIGHT:
1484 *params = mCaps.maxFramebufferHeight;
1485 break;
1486 case GL_MAX_FRAMEBUFFER_SAMPLES:
1487 *params = mCaps.maxFramebufferSamples;
1488 break;
1489 case GL_MAX_SAMPLE_MASK_WORDS:
1490 *params = mCaps.maxSampleMaskWords;
1491 break;
1492 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1493 *params = mCaps.maxColorTextureSamples;
1494 break;
1495 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1496 *params = mCaps.maxDepthTextureSamples;
1497 break;
1498 case GL_MAX_INTEGER_SAMPLES:
1499 *params = mCaps.maxIntegerSamples;
1500 break;
1501 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1502 *params = mCaps.maxVertexAttribRelativeOffset;
1503 break;
1504 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1505 *params = mCaps.maxVertexAttribBindings;
1506 break;
1507 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1508 *params = mCaps.maxVertexAttribStride;
1509 break;
1510 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1511 *params = mCaps.maxVertexAtomicCounterBuffers;
1512 break;
1513 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1514 *params = mCaps.maxVertexAtomicCounters;
1515 break;
1516 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1517 *params = mCaps.maxVertexImageUniforms;
1518 break;
1519 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1520 *params = mCaps.maxVertexShaderStorageBlocks;
1521 break;
1522 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1523 *params = mCaps.maxFragmentAtomicCounterBuffers;
1524 break;
1525 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1526 *params = mCaps.maxFragmentAtomicCounters;
1527 break;
1528 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1529 *params = mCaps.maxFragmentImageUniforms;
1530 break;
1531 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1532 *params = mCaps.maxFragmentShaderStorageBlocks;
1533 break;
1534 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1535 *params = mCaps.minProgramTextureGatherOffset;
1536 break;
1537 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1538 *params = mCaps.maxProgramTextureGatherOffset;
1539 break;
1540 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1541 *params = mCaps.maxComputeWorkGroupInvocations;
1542 break;
1543 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1544 *params = mCaps.maxComputeUniformBlocks;
1545 break;
1546 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1547 *params = mCaps.maxComputeTextureImageUnits;
1548 break;
1549 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1550 *params = mCaps.maxComputeSharedMemorySize;
1551 break;
1552 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1553 *params = mCaps.maxComputeUniformComponents;
1554 break;
1555 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1556 *params = mCaps.maxComputeAtomicCounterBuffers;
1557 break;
1558 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1559 *params = mCaps.maxComputeAtomicCounters;
1560 break;
1561 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1562 *params = mCaps.maxComputeImageUniforms;
1563 break;
1564 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1565 *params = mCaps.maxCombinedComputeUniformComponents;
1566 break;
1567 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1568 *params = mCaps.maxComputeShaderStorageBlocks;
1569 break;
1570 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1571 *params = mCaps.maxCombinedShaderOutputResources;
1572 break;
1573 case GL_MAX_UNIFORM_LOCATIONS:
1574 *params = mCaps.maxUniformLocations;
1575 break;
1576 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1577 *params = mCaps.maxAtomicCounterBufferBindings;
1578 break;
1579 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1580 *params = mCaps.maxAtomicCounterBufferSize;
1581 break;
1582 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1583 *params = mCaps.maxCombinedAtomicCounterBuffers;
1584 break;
1585 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1586 *params = mCaps.maxCombinedAtomicCounters;
1587 break;
1588 case GL_MAX_IMAGE_UNITS:
1589 *params = mCaps.maxImageUnits;
1590 break;
1591 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1592 *params = mCaps.maxCombinedImageUniforms;
1593 break;
1594 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1595 *params = mCaps.maxShaderStorageBufferBindings;
1596 break;
1597 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1598 *params = mCaps.maxCombinedShaderStorageBlocks;
1599 break;
1600 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1601 *params = mCaps.shaderStorageBufferOffsetAlignment;
1602 break;
1603 default:
1604 mGLState.getIntegerv(this, pname, params);
1605 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001606 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001607}
1608
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001609void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001610{
Shannon Woods53a94a82014-06-24 15:20:36 -04001611 // Queries about context capabilities and maximums are answered by Context.
1612 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001613 switch (pname)
1614 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001615 case GL_MAX_ELEMENT_INDEX:
1616 *params = mCaps.maxElementIndex;
1617 break;
1618 case GL_MAX_UNIFORM_BLOCK_SIZE:
1619 *params = mCaps.maxUniformBlockSize;
1620 break;
1621 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1622 *params = mCaps.maxCombinedVertexUniformComponents;
1623 break;
1624 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1625 *params = mCaps.maxCombinedFragmentUniformComponents;
1626 break;
1627 case GL_MAX_SERVER_WAIT_TIMEOUT:
1628 *params = mCaps.maxServerWaitTimeout;
1629 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001630
Jamie Madill231c7f52017-04-26 13:45:37 -04001631 // GL_EXT_disjoint_timer_query
1632 case GL_TIMESTAMP_EXT:
1633 *params = mImplementation->getTimestamp();
1634 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001635
Jamie Madill231c7f52017-04-26 13:45:37 -04001636 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1637 *params = mCaps.maxShaderStorageBlockSize;
1638 break;
1639 default:
1640 UNREACHABLE();
1641 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001642 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001643}
1644
Geoff Lang70d0f492015-12-10 17:45:46 -05001645void Context::getPointerv(GLenum pname, void **params) const
1646{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001647 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001648}
1649
Martin Radev66fb8202016-07-28 11:45:20 +03001650void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001651{
Shannon Woods53a94a82014-06-24 15:20:36 -04001652 // Queries about context capabilities and maximums are answered by Context.
1653 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001654
1655 GLenum nativeType;
1656 unsigned int numParams;
1657 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1658 ASSERT(queryStatus);
1659
1660 if (nativeType == GL_INT)
1661 {
1662 switch (target)
1663 {
1664 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1665 ASSERT(index < 3u);
1666 *data = mCaps.maxComputeWorkGroupCount[index];
1667 break;
1668 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1669 ASSERT(index < 3u);
1670 *data = mCaps.maxComputeWorkGroupSize[index];
1671 break;
1672 default:
1673 mGLState.getIntegeri_v(target, index, data);
1674 }
1675 }
1676 else
1677 {
1678 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1679 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001680}
1681
Martin Radev66fb8202016-07-28 11:45:20 +03001682void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001683{
Shannon Woods53a94a82014-06-24 15:20:36 -04001684 // Queries about context capabilities and maximums are answered by Context.
1685 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001686
1687 GLenum nativeType;
1688 unsigned int numParams;
1689 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1690 ASSERT(queryStatus);
1691
1692 if (nativeType == GL_INT_64_ANGLEX)
1693 {
1694 mGLState.getInteger64i_v(target, index, data);
1695 }
1696 else
1697 {
1698 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1699 }
1700}
1701
1702void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1703{
1704 // Queries about context capabilities and maximums are answered by Context.
1705 // Queries about current GL state values are answered by State.
1706
1707 GLenum nativeType;
1708 unsigned int numParams;
1709 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1710 ASSERT(queryStatus);
1711
1712 if (nativeType == GL_BOOL)
1713 {
1714 mGLState.getBooleani_v(target, index, data);
1715 }
1716 else
1717 {
1718 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1719 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001720}
1721
He Yunchao010e4db2017-03-03 14:22:06 +08001722void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1723{
1724 Buffer *buffer = mGLState.getTargetBuffer(target);
1725 QueryBufferParameteriv(buffer, pname, params);
1726}
1727
1728void Context::getFramebufferAttachmentParameteriv(GLenum target,
1729 GLenum attachment,
1730 GLenum pname,
1731 GLint *params)
1732{
1733 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1734 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1735}
1736
1737void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1738{
1739 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1740 QueryRenderbufferiv(this, renderbuffer, pname, params);
1741}
1742
1743void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1744{
1745 Texture *texture = getTargetTexture(target);
1746 QueryTexParameterfv(texture, pname, params);
1747}
1748
1749void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1750{
1751 Texture *texture = getTargetTexture(target);
1752 QueryTexParameteriv(texture, pname, params);
1753}
1754void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1755{
1756 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001757 SetTexParameterf(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001758 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001759}
1760
1761void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1762{
1763 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001764 SetTexParameterfv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001765 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001766}
1767
1768void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1769{
1770 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001771 SetTexParameteri(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001772 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001773}
1774
1775void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1776{
1777 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001778 SetTexParameteriv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001779 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001780}
1781
Jamie Madill675fe712016-12-19 13:07:54 -05001782void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001783{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001784 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001785 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1786 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001787}
1788
Jamie Madill675fe712016-12-19 13:07:54 -05001789void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001790{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001791 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001792 ANGLE_CONTEXT_TRY(
1793 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1794 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001795}
1796
Jamie Madill876429b2017-04-20 15:46:24 -04001797void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001798{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001799 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001800 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001801}
1802
Jamie Madill675fe712016-12-19 13:07:54 -05001803void Context::drawElementsInstanced(GLenum mode,
1804 GLsizei count,
1805 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001806 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001807 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001808{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001809 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001810 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001811 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001812}
1813
Jamie Madill675fe712016-12-19 13:07:54 -05001814void Context::drawRangeElements(GLenum mode,
1815 GLuint start,
1816 GLuint end,
1817 GLsizei count,
1818 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001819 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001820{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001821 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001822 ANGLE_CONTEXT_TRY(
1823 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001824}
1825
Jamie Madill876429b2017-04-20 15:46:24 -04001826void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001827{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001828 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001829 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001830}
1831
Jamie Madill876429b2017-04-20 15:46:24 -04001832void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001833{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001834 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001835 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001836}
1837
Jamie Madill675fe712016-12-19 13:07:54 -05001838void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001839{
Jamie Madill675fe712016-12-19 13:07:54 -05001840 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001841}
1842
Jamie Madill675fe712016-12-19 13:07:54 -05001843void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001844{
Jamie Madill675fe712016-12-19 13:07:54 -05001845 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001846}
1847
Austin Kinross6ee1e782015-05-29 17:05:37 -07001848void Context::insertEventMarker(GLsizei length, const char *marker)
1849{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001850 ASSERT(mImplementation);
1851 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001852}
1853
1854void Context::pushGroupMarker(GLsizei length, const char *marker)
1855{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001856 ASSERT(mImplementation);
1857 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001858}
1859
1860void Context::popGroupMarker()
1861{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001862 ASSERT(mImplementation);
1863 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001864}
1865
Geoff Langd8605522016-04-13 10:19:12 -04001866void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1867{
1868 Program *programObject = getProgram(program);
1869 ASSERT(programObject);
1870
1871 programObject->bindUniformLocation(location, name);
1872}
1873
Sami Väisänena797e062016-05-12 15:23:40 +03001874void Context::setCoverageModulation(GLenum components)
1875{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001876 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001877}
1878
Sami Väisänene45e53b2016-05-25 10:36:04 +03001879void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1880{
1881 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1882}
1883
1884void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1885{
1886 GLfloat I[16];
1887 angle::Matrix<GLfloat>::setToIdentity(I);
1888
1889 mGLState.loadPathRenderingMatrix(matrixMode, I);
1890}
1891
1892void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1893{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001894 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001895 if (!pathObj)
1896 return;
1897
1898 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1899 syncRendererState();
1900
1901 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1902}
1903
1904void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1905{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001906 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001907 if (!pathObj)
1908 return;
1909
1910 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1911 syncRendererState();
1912
1913 mImplementation->stencilStrokePath(pathObj, reference, mask);
1914}
1915
1916void Context::coverFillPath(GLuint path, GLenum coverMode)
1917{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001918 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001919 if (!pathObj)
1920 return;
1921
1922 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1923 syncRendererState();
1924
1925 mImplementation->coverFillPath(pathObj, coverMode);
1926}
1927
1928void Context::coverStrokePath(GLuint path, GLenum coverMode)
1929{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001930 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001931 if (!pathObj)
1932 return;
1933
1934 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1935 syncRendererState();
1936
1937 mImplementation->coverStrokePath(pathObj, coverMode);
1938}
1939
1940void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1941{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001942 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001943 if (!pathObj)
1944 return;
1945
1946 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1947 syncRendererState();
1948
1949 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1950}
1951
1952void Context::stencilThenCoverStrokePath(GLuint path,
1953 GLint reference,
1954 GLuint mask,
1955 GLenum coverMode)
1956{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001957 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001958 if (!pathObj)
1959 return;
1960
1961 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1962 syncRendererState();
1963
1964 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1965}
1966
Sami Väisänend59ca052016-06-21 16:10:00 +03001967void Context::coverFillPathInstanced(GLsizei numPaths,
1968 GLenum pathNameType,
1969 const void *paths,
1970 GLuint pathBase,
1971 GLenum coverMode,
1972 GLenum transformType,
1973 const GLfloat *transformValues)
1974{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001975 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001976
1977 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1978 syncRendererState();
1979
1980 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1981}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001982
Sami Väisänend59ca052016-06-21 16:10:00 +03001983void Context::coverStrokePathInstanced(GLsizei numPaths,
1984 GLenum pathNameType,
1985 const void *paths,
1986 GLuint pathBase,
1987 GLenum coverMode,
1988 GLenum transformType,
1989 const GLfloat *transformValues)
1990{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001991 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001992
1993 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1994 syncRendererState();
1995
1996 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1997 transformValues);
1998}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001999
Sami Väisänend59ca052016-06-21 16:10:00 +03002000void Context::stencilFillPathInstanced(GLsizei numPaths,
2001 GLenum pathNameType,
2002 const void *paths,
2003 GLuint pathBase,
2004 GLenum fillMode,
2005 GLuint mask,
2006 GLenum transformType,
2007 const GLfloat *transformValues)
2008{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002009 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002010
2011 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2012 syncRendererState();
2013
2014 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2015 transformValues);
2016}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002017
Sami Väisänend59ca052016-06-21 16:10:00 +03002018void Context::stencilStrokePathInstanced(GLsizei numPaths,
2019 GLenum pathNameType,
2020 const void *paths,
2021 GLuint pathBase,
2022 GLint reference,
2023 GLuint mask,
2024 GLenum transformType,
2025 const GLfloat *transformValues)
2026{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002027 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002028
2029 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2030 syncRendererState();
2031
2032 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2033 transformValues);
2034}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002035
Sami Väisänend59ca052016-06-21 16:10:00 +03002036void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2037 GLenum pathNameType,
2038 const void *paths,
2039 GLuint pathBase,
2040 GLenum fillMode,
2041 GLuint mask,
2042 GLenum coverMode,
2043 GLenum transformType,
2044 const GLfloat *transformValues)
2045{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002046 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002047
2048 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2049 syncRendererState();
2050
2051 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2052 transformType, transformValues);
2053}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002054
Sami Väisänend59ca052016-06-21 16:10:00 +03002055void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2056 GLenum pathNameType,
2057 const void *paths,
2058 GLuint pathBase,
2059 GLint reference,
2060 GLuint mask,
2061 GLenum coverMode,
2062 GLenum transformType,
2063 const GLfloat *transformValues)
2064{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002065 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002066
2067 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2068 syncRendererState();
2069
2070 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2071 transformType, transformValues);
2072}
2073
Sami Väisänen46eaa942016-06-29 10:26:37 +03002074void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2075{
2076 auto *programObject = getProgram(program);
2077
2078 programObject->bindFragmentInputLocation(location, name);
2079}
2080
2081void Context::programPathFragmentInputGen(GLuint program,
2082 GLint location,
2083 GLenum genMode,
2084 GLint components,
2085 const GLfloat *coeffs)
2086{
2087 auto *programObject = getProgram(program);
2088
Jamie Madillbd044ed2017-06-05 12:59:21 -04002089 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002090}
2091
jchen1015015f72017-03-16 13:54:21 +08002092GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2093{
jchen10fd7c3b52017-03-21 15:36:03 +08002094 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002095 return QueryProgramResourceIndex(programObject, programInterface, name);
2096}
2097
jchen10fd7c3b52017-03-21 15:36:03 +08002098void Context::getProgramResourceName(GLuint program,
2099 GLenum programInterface,
2100 GLuint index,
2101 GLsizei bufSize,
2102 GLsizei *length,
2103 GLchar *name)
2104{
2105 const auto *programObject = getProgram(program);
2106 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2107}
2108
jchen10191381f2017-04-11 13:59:04 +08002109GLint Context::getProgramResourceLocation(GLuint program,
2110 GLenum programInterface,
2111 const GLchar *name)
2112{
2113 const auto *programObject = getProgram(program);
2114 return QueryProgramResourceLocation(programObject, programInterface, name);
2115}
2116
jchen10880683b2017-04-12 16:21:55 +08002117void Context::getProgramResourceiv(GLuint program,
2118 GLenum programInterface,
2119 GLuint index,
2120 GLsizei propCount,
2121 const GLenum *props,
2122 GLsizei bufSize,
2123 GLsizei *length,
2124 GLint *params)
2125{
2126 const auto *programObject = getProgram(program);
2127 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2128 length, params);
2129}
2130
jchen10d9cd7b72017-08-30 15:04:25 +08002131void Context::getProgramInterfaceiv(GLuint program,
2132 GLenum programInterface,
2133 GLenum pname,
2134 GLint *params)
2135{
2136 const auto *programObject = getProgram(program);
2137 QueryProgramInterfaceiv(programObject, programInterface, pname, params);
2138}
2139
Jamie Madill71c88b32017-09-14 22:20:29 -04002140void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002141{
Geoff Langda5777c2014-07-11 09:52:58 -04002142 if (error.isError())
2143 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002144 GLenum code = error.getCode();
2145 mErrors.insert(code);
2146 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2147 {
2148 markContextLost();
2149 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002150
2151 if (!error.getMessage().empty())
2152 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002153 auto *debug = &mGLState.getDebug();
2154 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2155 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002156 }
Geoff Langda5777c2014-07-11 09:52:58 -04002157 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002158}
2159
2160// Get one of the recorded errors and clear its flag, if any.
2161// [OpenGL ES 2.0.24] section 2.5 page 13.
2162GLenum Context::getError()
2163{
Geoff Langda5777c2014-07-11 09:52:58 -04002164 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002165 {
Geoff Langda5777c2014-07-11 09:52:58 -04002166 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002167 }
Geoff Langda5777c2014-07-11 09:52:58 -04002168 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002169 {
Geoff Langda5777c2014-07-11 09:52:58 -04002170 GLenum error = *mErrors.begin();
2171 mErrors.erase(mErrors.begin());
2172 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002173 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002174}
2175
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002176// NOTE: this function should not assume that this context is current!
2177void Context::markContextLost()
2178{
2179 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002180 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002181 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002182 mContextLostForced = true;
2183 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002184 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002185}
2186
2187bool Context::isContextLost()
2188{
2189 return mContextLost;
2190}
2191
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002192GLenum Context::getResetStatus()
2193{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002194 // Even if the application doesn't want to know about resets, we want to know
2195 // as it will allow us to skip all the calls.
2196 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002197 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002198 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002199 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002200 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002201 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002202
2203 // EXT_robustness, section 2.6: If the reset notification behavior is
2204 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2205 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2206 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002207 }
2208
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002209 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2210 // status should be returned at least once, and GL_NO_ERROR should be returned
2211 // once the device has finished resetting.
2212 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002213 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002214 ASSERT(mResetStatus == GL_NO_ERROR);
2215 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002216
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002217 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002218 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002219 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002220 }
2221 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002222 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002223 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002224 // If markContextLost was used to mark the context lost then
2225 // assume that is not recoverable, and continue to report the
2226 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002227 mResetStatus = mImplementation->getResetStatus();
2228 }
Jamie Madill893ab082014-05-16 16:56:10 -04002229
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002230 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002231}
2232
2233bool Context::isResetNotificationEnabled()
2234{
2235 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2236}
2237
Corentin Walleze3b10e82015-05-20 11:06:25 -04002238const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002239{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002240 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002241}
2242
2243EGLenum Context::getClientType() const
2244{
2245 return mClientType;
2246}
2247
2248EGLenum Context::getRenderBuffer() const
2249{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002250 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2251 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002252 {
2253 return EGL_NONE;
2254 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002255
2256 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2257 ASSERT(backAttachment != nullptr);
2258 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002259}
2260
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002261VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002262{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002263 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002264 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2265 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002266 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002267 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2268 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002269
Jamie Madill96a483b2017-06-27 16:49:21 -04002270 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002271 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002272
2273 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002274}
2275
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002276TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002277{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002278 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002279 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2280 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002281 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002282 transformFeedback =
2283 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002284 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002285 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002286 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002287
2288 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002289}
2290
2291bool Context::isVertexArrayGenerated(GLuint vertexArray)
2292{
Jamie Madill96a483b2017-06-27 16:49:21 -04002293 ASSERT(mVertexArrayMap.contains(0));
2294 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002295}
2296
2297bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2298{
Jamie Madill96a483b2017-06-27 16:49:21 -04002299 ASSERT(mTransformFeedbackMap.contains(0));
2300 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002301}
2302
Shannon Woods53a94a82014-06-24 15:20:36 -04002303void Context::detachTexture(GLuint texture)
2304{
2305 // Simple pass-through to State's detachTexture method, as textures do not require
2306 // allocation map management either here or in the resource manager at detach time.
2307 // Zero textures are held by the Context, and we don't attempt to request them from
2308 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002309 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002310}
2311
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002312void Context::detachBuffer(GLuint buffer)
2313{
Yuly Novikov5807a532015-12-03 13:01:22 -05002314 // Simple pass-through to State's detachBuffer method, since
2315 // only buffer attachments to container objects that are bound to the current context
2316 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002317
Yuly Novikov5807a532015-12-03 13:01:22 -05002318 // [OpenGL ES 3.2] section 5.1.2 page 45:
2319 // Attachments to unbound container objects, such as
2320 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2321 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002322 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002323}
2324
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002325void Context::detachFramebuffer(GLuint framebuffer)
2326{
Shannon Woods53a94a82014-06-24 15:20:36 -04002327 // Framebuffer detachment is handled by Context, because 0 is a valid
2328 // Framebuffer object, and a pointer to it must be passed from Context
2329 // to State at binding time.
2330
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002331 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002332 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2333 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2334 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002335
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002336 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002337 {
2338 bindReadFramebuffer(0);
2339 }
2340
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002341 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002342 {
2343 bindDrawFramebuffer(0);
2344 }
2345}
2346
2347void Context::detachRenderbuffer(GLuint renderbuffer)
2348{
Jamie Madilla02315b2017-02-23 14:14:47 -05002349 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002350}
2351
Jamie Madill57a89722013-07-02 11:57:03 -04002352void Context::detachVertexArray(GLuint vertexArray)
2353{
Jamie Madill77a72f62015-04-14 11:18:32 -04002354 // Vertex array detachment is handled by Context, because 0 is a valid
2355 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002356 // binding time.
2357
Jamie Madill57a89722013-07-02 11:57:03 -04002358 // [OpenGL ES 3.0.2] section 2.10 page 43:
2359 // If a vertex array object that is currently bound is deleted, the binding
2360 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002361 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002362 {
2363 bindVertexArray(0);
2364 }
2365}
2366
Geoff Langc8058452014-02-03 12:04:11 -05002367void Context::detachTransformFeedback(GLuint transformFeedback)
2368{
Corentin Walleza2257da2016-04-19 16:43:12 -04002369 // Transform feedback detachment is handled by Context, because 0 is a valid
2370 // transform feedback, and a pointer to it must be passed from Context to State at
2371 // binding time.
2372
2373 // The OpenGL specification doesn't mention what should happen when the currently bound
2374 // transform feedback object is deleted. Since it is a container object, we treat it like
2375 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002376 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002377 {
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04002378 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Corentin Walleza2257da2016-04-19 16:43:12 -04002379 }
Geoff Langc8058452014-02-03 12:04:11 -05002380}
2381
Jamie Madilldc356042013-07-19 16:36:57 -04002382void Context::detachSampler(GLuint sampler)
2383{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002384 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002385}
2386
Yunchao Hea336b902017-08-02 16:05:21 +08002387void Context::detachProgramPipeline(GLuint pipeline)
2388{
2389 mGLState.detachProgramPipeline(this, pipeline);
2390}
2391
Jamie Madill3ef140a2017-08-26 23:11:21 -04002392void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002393{
Shaodde78e82017-05-22 14:13:27 +08002394 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002395}
2396
Jamie Madille29d1672013-07-19 16:36:57 -04002397void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2398{
Geoff Langc1984ed2016-10-07 12:41:00 -04002399 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002400 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002401 SetSamplerParameteri(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002402 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002403}
Jamie Madille29d1672013-07-19 16:36:57 -04002404
Geoff Langc1984ed2016-10-07 12:41:00 -04002405void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2406{
2407 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002408 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002409 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002410 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002411}
2412
2413void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2414{
Geoff Langc1984ed2016-10-07 12:41:00 -04002415 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002416 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002417 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002418 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002419}
2420
Geoff Langc1984ed2016-10-07 12:41:00 -04002421void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002422{
Geoff Langc1984ed2016-10-07 12:41:00 -04002423 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002424 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002425 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002426 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002427}
2428
Geoff Langc1984ed2016-10-07 12:41:00 -04002429void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002430{
Geoff Langc1984ed2016-10-07 12:41:00 -04002431 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002432 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002433 QuerySamplerParameteriv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002434 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002435}
Jamie Madill9675b802013-07-19 16:36:59 -04002436
Geoff Langc1984ed2016-10-07 12:41:00 -04002437void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2438{
2439 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002440 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002441 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002442 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002443}
2444
Olli Etuahof0fee072016-03-30 15:11:58 +03002445void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2446{
2447 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002448 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002449}
2450
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002451void Context::initRendererString()
2452{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002453 std::ostringstream rendererString;
2454 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002455 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002456 rendererString << ")";
2457
Geoff Langcec35902014-04-16 10:52:36 -04002458 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002459}
2460
Geoff Langc339c4e2016-11-29 10:37:36 -05002461void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002462{
Geoff Langc339c4e2016-11-29 10:37:36 -05002463 const Version &clientVersion = getClientVersion();
2464
2465 std::ostringstream versionString;
2466 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2467 << ANGLE_VERSION_STRING << ")";
2468 mVersionString = MakeStaticString(versionString.str());
2469
2470 std::ostringstream shadingLanguageVersionString;
2471 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2472 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2473 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2474 << ")";
2475 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002476}
2477
Geoff Langcec35902014-04-16 10:52:36 -04002478void Context::initExtensionStrings()
2479{
Geoff Langc339c4e2016-11-29 10:37:36 -05002480 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2481 std::ostringstream combinedStringStream;
2482 std::copy(strings.begin(), strings.end(),
2483 std::ostream_iterator<const char *>(combinedStringStream, " "));
2484 return MakeStaticString(combinedStringStream.str());
2485 };
2486
2487 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002488 for (const auto &extensionString : mExtensions.getStrings())
2489 {
2490 mExtensionStrings.push_back(MakeStaticString(extensionString));
2491 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002492 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002493
Bryan Bernhart58806562017-01-05 13:09:31 -08002494 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2495
Geoff Langc339c4e2016-11-29 10:37:36 -05002496 mRequestableExtensionStrings.clear();
2497 for (const auto &extensionInfo : GetExtensionInfoMap())
2498 {
2499 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002500 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2501 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002502 {
2503 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2504 }
2505 }
2506 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002507}
2508
Geoff Langc339c4e2016-11-29 10:37:36 -05002509const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002510{
Geoff Langc339c4e2016-11-29 10:37:36 -05002511 switch (name)
2512 {
2513 case GL_VENDOR:
2514 return reinterpret_cast<const GLubyte *>("Google Inc.");
2515
2516 case GL_RENDERER:
2517 return reinterpret_cast<const GLubyte *>(mRendererString);
2518
2519 case GL_VERSION:
2520 return reinterpret_cast<const GLubyte *>(mVersionString);
2521
2522 case GL_SHADING_LANGUAGE_VERSION:
2523 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2524
2525 case GL_EXTENSIONS:
2526 return reinterpret_cast<const GLubyte *>(mExtensionString);
2527
2528 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2529 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2530
2531 default:
2532 UNREACHABLE();
2533 return nullptr;
2534 }
Geoff Langcec35902014-04-16 10:52:36 -04002535}
2536
Geoff Langc339c4e2016-11-29 10:37:36 -05002537const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002538{
Geoff Langc339c4e2016-11-29 10:37:36 -05002539 switch (name)
2540 {
2541 case GL_EXTENSIONS:
2542 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2543
2544 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2545 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2546
2547 default:
2548 UNREACHABLE();
2549 return nullptr;
2550 }
Geoff Langcec35902014-04-16 10:52:36 -04002551}
2552
2553size_t Context::getExtensionStringCount() const
2554{
2555 return mExtensionStrings.size();
2556}
2557
Geoff Langc339c4e2016-11-29 10:37:36 -05002558void Context::requestExtension(const char *name)
2559{
2560 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2561 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2562 const auto &extension = extensionInfos.at(name);
2563 ASSERT(extension.Requestable);
2564
2565 if (mExtensions.*(extension.ExtensionsMember))
2566 {
2567 // Extension already enabled
2568 return;
2569 }
2570
2571 mExtensions.*(extension.ExtensionsMember) = true;
2572 updateCaps();
2573 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002574
Jamie Madill2f348d22017-06-05 10:50:59 -04002575 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2576 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002577
Jamie Madill81c2e252017-09-09 23:32:46 -04002578 // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
2579 // sampleable.
2580 mState.mTextures->signalAllTexturesDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002581 for (auto &zeroTexture : mZeroTextures)
2582 {
Jamie Madill81c2e252017-09-09 23:32:46 -04002583 zeroTexture.second->signalDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002584 }
2585
2586 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002587}
2588
2589size_t Context::getRequestableExtensionStringCount() const
2590{
2591 return mRequestableExtensionStrings.size();
2592}
2593
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002594void Context::beginTransformFeedback(GLenum primitiveMode)
2595{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002596 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002597 ASSERT(transformFeedback != nullptr);
2598 ASSERT(!transformFeedback->isPaused());
2599
Jamie Madill6c1f6712017-02-14 19:08:04 -05002600 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002601}
2602
2603bool Context::hasActiveTransformFeedback(GLuint program) const
2604{
2605 for (auto pair : mTransformFeedbackMap)
2606 {
2607 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2608 {
2609 return true;
2610 }
2611 }
2612 return false;
2613}
2614
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002615void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002616{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002617 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002618
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002619 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002620
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002621 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002622
Geoff Langeb66a6e2016-10-31 13:06:12 -04002623 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002624 {
2625 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002626 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002627 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002628 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002629 mExtensions.multiview = false;
2630 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002631 }
2632
Geoff Langeb66a6e2016-10-31 13:06:12 -04002633 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002634 {
2635 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002636 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002637 }
2638
Jamie Madill00ed7a12016-05-19 13:13:38 -04002639 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002640 mExtensions.bindUniformLocation = true;
2641 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002642 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002643 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002644 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002645
2646 // Enable the no error extension if the context was created with the flag.
2647 mExtensions.noError = mSkipValidation;
2648
Corentin Wallezccab69d2017-01-27 16:57:15 -05002649 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002650 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002651
Geoff Lang70d0f492015-12-10 17:45:46 -05002652 // Explicitly enable GL_KHR_debug
2653 mExtensions.debug = true;
2654 mExtensions.maxDebugMessageLength = 1024;
2655 mExtensions.maxDebugLoggedMessages = 1024;
2656 mExtensions.maxDebugGroupStackDepth = 1024;
2657 mExtensions.maxLabelLength = 1024;
2658
Geoff Langff5b2d52016-09-07 11:32:23 -04002659 // Explicitly enable GL_ANGLE_robust_client_memory
2660 mExtensions.robustClientMemory = true;
2661
Jamie Madille08a1d32017-03-07 17:24:06 -05002662 // Determine robust resource init availability from EGL.
2663 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002664 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002665
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08002666 // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
2667 // supports it.
2668 mExtensions.robustBufferAccessBehavior =
2669 mRobustAccess && mExtensions.robustBufferAccessBehavior;
2670
Jamie Madillc43be722017-07-13 16:22:14 -04002671 // Enable the cache control query unconditionally.
2672 mExtensions.programCacheControl = true;
2673
Geoff Lang301d1612014-07-09 10:34:37 -04002674 // Apply implementation limits
2675 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002676 mCaps.maxVertexAttribBindings =
2677 getClientVersion() < ES_3_1
2678 ? mCaps.maxVertexAttributes
2679 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2680
Jamie Madill231c7f52017-04-26 13:45:37 -04002681 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2682 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2683 mCaps.maxVertexOutputComponents =
2684 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002685
Jamie Madill231c7f52017-04-26 13:45:37 -04002686 mCaps.maxFragmentInputComponents =
2687 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002688
Geoff Langc287ea62016-09-16 14:46:51 -04002689 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002690 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002691 for (const auto &extensionInfo : GetExtensionInfoMap())
2692 {
2693 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002694 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002695 {
2696 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2697 }
2698 }
2699
2700 // Generate texture caps
2701 updateCaps();
2702}
2703
2704void Context::updateCaps()
2705{
Geoff Lang900013c2014-07-07 11:32:19 -04002706 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002707 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002708
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002709 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002710 {
Geoff Langca271392017-04-05 12:30:00 -04002711 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002712 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002713
Geoff Langca271392017-04-05 12:30:00 -04002714 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002715
Geoff Lang0d8b7242015-09-09 14:56:53 -04002716 // Update the format caps based on the client version and extensions.
2717 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2718 // ES3.
2719 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002720 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002721 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002722 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002723 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002724 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002725
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002726 // OpenGL ES does not support multisampling with non-rendererable formats
2727 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002728 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002729 (getClientVersion() < ES_3_1 &&
2730 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002731 {
Geoff Langd87878e2014-09-19 15:42:59 -04002732 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002733 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002734 else
2735 {
2736 // We may have limited the max samples for some required renderbuffer formats due to
2737 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2738 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2739
2740 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2741 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2742 // exception of signed and unsigned integer formats."
2743 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2744 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2745 {
2746 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2747 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2748 }
2749
2750 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2751 if (getClientVersion() >= ES_3_1)
2752 {
2753 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2754 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2755 // the exception that the signed and unsigned integer formats are required only to
2756 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2757 // multisamples, which must be at least one."
2758 if (formatInfo.componentType == GL_INT ||
2759 formatInfo.componentType == GL_UNSIGNED_INT)
2760 {
2761 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2762 }
2763
2764 // GLES 3.1 section 19.3.1.
2765 if (formatCaps.texturable)
2766 {
2767 if (formatInfo.depthBits > 0)
2768 {
2769 mCaps.maxDepthTextureSamples =
2770 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2771 }
2772 else if (formatInfo.redBits > 0)
2773 {
2774 mCaps.maxColorTextureSamples =
2775 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2776 }
2777 }
2778 }
2779 }
Geoff Langd87878e2014-09-19 15:42:59 -04002780
2781 if (formatCaps.texturable && formatInfo.compressed)
2782 {
Geoff Langca271392017-04-05 12:30:00 -04002783 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002784 }
2785
Geoff Langca271392017-04-05 12:30:00 -04002786 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002787 }
Jamie Madill32447362017-06-28 14:53:52 -04002788
2789 // If program binary is disabled, blank out the memory cache pointer.
2790 if (!mImplementation->getNativeExtensions().getProgramBinary)
2791 {
2792 mMemoryProgramCache = nullptr;
2793 }
Geoff Lang493daf52014-07-03 13:38:44 -04002794}
2795
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002796void Context::initWorkarounds()
2797{
Jamie Madill761b02c2017-06-23 16:27:06 -04002798 // Apply back-end workarounds.
2799 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2800
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002801 // Lose the context upon out of memory error if the application is
2802 // expecting to watch for those events.
2803 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2804}
2805
Jamie Madill1b94d432015-08-07 13:23:23 -04002806void Context::syncRendererState()
2807{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002808 mGLState.syncDirtyObjects(this);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002809 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002810 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002811 mGLState.clearDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -04002812}
2813
Jamie Madillad9f24e2016-02-12 09:27:24 -05002814void Context::syncRendererState(const State::DirtyBits &bitMask,
2815 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002816{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002817 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002818 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002819 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002820 mGLState.clearDirtyBits(dirtyBits);
Jamie Madill1b94d432015-08-07 13:23:23 -04002821}
Jamie Madillc29968b2016-01-20 11:17:23 -05002822
2823void Context::blitFramebuffer(GLint srcX0,
2824 GLint srcY0,
2825 GLint srcX1,
2826 GLint srcY1,
2827 GLint dstX0,
2828 GLint dstY0,
2829 GLint dstX1,
2830 GLint dstY1,
2831 GLbitfield mask,
2832 GLenum filter)
2833{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002834 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002835 ASSERT(drawFramebuffer);
2836
2837 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2838 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2839
Jamie Madillad9f24e2016-02-12 09:27:24 -05002840 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002841
Jamie Madillc564c072017-06-01 12:45:42 -04002842 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002843}
Jamie Madillc29968b2016-01-20 11:17:23 -05002844
2845void Context::clear(GLbitfield mask)
2846{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002847 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002848 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002849}
2850
2851void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2852{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002853 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002854 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002855}
2856
2857void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2858{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002859 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002860 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002861}
2862
2863void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2864{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002865 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002866 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002867}
2868
2869void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2870{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002871 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002872 ASSERT(framebufferObject);
2873
2874 // If a buffer is not present, the clear has no effect
2875 if (framebufferObject->getDepthbuffer() == nullptr &&
2876 framebufferObject->getStencilbuffer() == nullptr)
2877 {
2878 return;
2879 }
2880
Jamie Madillad9f24e2016-02-12 09:27:24 -05002881 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002882 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002883}
2884
2885void Context::readPixels(GLint x,
2886 GLint y,
2887 GLsizei width,
2888 GLsizei height,
2889 GLenum format,
2890 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002891 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002892{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002893 if (width == 0 || height == 0)
2894 {
2895 return;
2896 }
2897
Jamie Madillad9f24e2016-02-12 09:27:24 -05002898 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002899
Jamie Madillb6664922017-07-25 12:55:04 -04002900 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2901 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002902
2903 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002904 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002905}
2906
2907void Context::copyTexImage2D(GLenum target,
2908 GLint level,
2909 GLenum internalformat,
2910 GLint x,
2911 GLint y,
2912 GLsizei width,
2913 GLsizei height,
2914 GLint border)
2915{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002916 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002917 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002918
Jamie Madillc29968b2016-01-20 11:17:23 -05002919 Rectangle sourceArea(x, y, width, height);
2920
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002921 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002922 Texture *texture =
2923 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002924 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002925}
2926
2927void Context::copyTexSubImage2D(GLenum target,
2928 GLint level,
2929 GLint xoffset,
2930 GLint yoffset,
2931 GLint x,
2932 GLint y,
2933 GLsizei width,
2934 GLsizei height)
2935{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002936 if (width == 0 || height == 0)
2937 {
2938 return;
2939 }
2940
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002941 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002942 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002943
Jamie Madillc29968b2016-01-20 11:17:23 -05002944 Offset destOffset(xoffset, yoffset, 0);
2945 Rectangle sourceArea(x, y, width, height);
2946
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002947 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002948 Texture *texture =
2949 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002950 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002951}
2952
2953void Context::copyTexSubImage3D(GLenum target,
2954 GLint level,
2955 GLint xoffset,
2956 GLint yoffset,
2957 GLint zoffset,
2958 GLint x,
2959 GLint y,
2960 GLsizei width,
2961 GLsizei height)
2962{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002963 if (width == 0 || height == 0)
2964 {
2965 return;
2966 }
2967
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002968 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002969 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002970
Jamie Madillc29968b2016-01-20 11:17:23 -05002971 Offset destOffset(xoffset, yoffset, zoffset);
2972 Rectangle sourceArea(x, y, width, height);
2973
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002974 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002975 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002976 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002977}
2978
2979void Context::framebufferTexture2D(GLenum target,
2980 GLenum attachment,
2981 GLenum textarget,
2982 GLuint texture,
2983 GLint level)
2984{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002985 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002986 ASSERT(framebuffer);
2987
2988 if (texture != 0)
2989 {
2990 Texture *textureObj = getTexture(texture);
2991
2992 ImageIndex index = ImageIndex::MakeInvalid();
2993
2994 if (textarget == GL_TEXTURE_2D)
2995 {
2996 index = ImageIndex::Make2D(level);
2997 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002998 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
2999 {
3000 index = ImageIndex::MakeRectangle(level);
3001 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08003002 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
3003 {
3004 ASSERT(level == 0);
3005 index = ImageIndex::Make2DMultisample();
3006 }
Jamie Madillc29968b2016-01-20 11:17:23 -05003007 else
3008 {
3009 ASSERT(IsCubeMapTextureTarget(textarget));
3010 index = ImageIndex::MakeCube(textarget, level);
3011 }
3012
Jamie Madilla02315b2017-02-23 14:14:47 -05003013 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003014 }
3015 else
3016 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003017 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003018 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003019
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003020 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003021}
3022
3023void Context::framebufferRenderbuffer(GLenum target,
3024 GLenum attachment,
3025 GLenum renderbuffertarget,
3026 GLuint renderbuffer)
3027{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003028 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003029 ASSERT(framebuffer);
3030
3031 if (renderbuffer != 0)
3032 {
3033 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003034
3035 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003036 renderbufferObject);
3037 }
3038 else
3039 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003040 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003041 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003042
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003043 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003044}
3045
3046void Context::framebufferTextureLayer(GLenum target,
3047 GLenum attachment,
3048 GLuint texture,
3049 GLint level,
3050 GLint layer)
3051{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003052 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003053 ASSERT(framebuffer);
3054
3055 if (texture != 0)
3056 {
3057 Texture *textureObject = getTexture(texture);
3058
3059 ImageIndex index = ImageIndex::MakeInvalid();
3060
3061 if (textureObject->getTarget() == GL_TEXTURE_3D)
3062 {
3063 index = ImageIndex::Make3D(level, layer);
3064 }
3065 else
3066 {
3067 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3068 index = ImageIndex::Make2DArray(level, layer);
3069 }
3070
Jamie Madilla02315b2017-02-23 14:14:47 -05003071 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003072 }
3073 else
3074 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003075 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003076 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003077
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003078 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003079}
3080
Martin Radev137032d2017-07-13 10:11:12 +03003081void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3082 GLenum attachment,
3083 GLuint texture,
3084 GLint level,
3085 GLint baseViewIndex,
3086 GLsizei numViews)
3087{
Martin Radev82ef7742017-08-08 17:44:58 +03003088 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3089 ASSERT(framebuffer);
3090
3091 if (texture != 0)
3092 {
3093 Texture *textureObj = getTexture(texture);
3094
Martin Radev18b75ba2017-08-15 15:50:40 +03003095 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003096 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3097 numViews, baseViewIndex);
3098 }
3099 else
3100 {
3101 framebuffer->resetAttachment(this, attachment);
3102 }
3103
3104 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003105}
3106
3107void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3108 GLenum attachment,
3109 GLuint texture,
3110 GLint level,
3111 GLsizei numViews,
3112 const GLint *viewportOffsets)
3113{
Martin Radev5dae57b2017-07-14 16:15:55 +03003114 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3115 ASSERT(framebuffer);
3116
3117 if (texture != 0)
3118 {
3119 Texture *textureObj = getTexture(texture);
3120
3121 ImageIndex index = ImageIndex::Make2D(level);
3122 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3123 textureObj, numViews, viewportOffsets);
3124 }
3125 else
3126 {
3127 framebuffer->resetAttachment(this, attachment);
3128 }
3129
3130 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003131}
3132
Jamie Madillc29968b2016-01-20 11:17:23 -05003133void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3134{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003135 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003136 ASSERT(framebuffer);
3137 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003138 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003139}
3140
3141void Context::readBuffer(GLenum mode)
3142{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003143 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003144 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003145 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003146}
3147
3148void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3149{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003150 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003151 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003152
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003153 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003154 ASSERT(framebuffer);
3155
3156 // The specification isn't clear what should be done when the framebuffer isn't complete.
3157 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003158 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003159}
3160
3161void Context::invalidateFramebuffer(GLenum target,
3162 GLsizei numAttachments,
3163 const GLenum *attachments)
3164{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003165 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003166 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003167
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003168 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003169 ASSERT(framebuffer);
3170
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003171 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003172 {
Jamie Madill437fa652016-05-03 15:13:24 -04003173 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003174 }
Jamie Madill437fa652016-05-03 15:13:24 -04003175
Jamie Madill4928b7c2017-06-20 12:57:39 -04003176 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003177}
3178
3179void Context::invalidateSubFramebuffer(GLenum target,
3180 GLsizei numAttachments,
3181 const GLenum *attachments,
3182 GLint x,
3183 GLint y,
3184 GLsizei width,
3185 GLsizei height)
3186{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003187 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003188 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003189
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003190 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003191 ASSERT(framebuffer);
3192
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003193 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003194 {
Jamie Madill437fa652016-05-03 15:13:24 -04003195 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003196 }
Jamie Madill437fa652016-05-03 15:13:24 -04003197
3198 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003199 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003200}
3201
Jamie Madill73a84962016-02-12 09:27:23 -05003202void Context::texImage2D(GLenum target,
3203 GLint level,
3204 GLint internalformat,
3205 GLsizei width,
3206 GLsizei height,
3207 GLint border,
3208 GLenum format,
3209 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003210 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003211{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003212 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003213
3214 Extents size(width, height, 1);
3215 Texture *texture =
3216 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003217 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3218 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003219}
3220
3221void Context::texImage3D(GLenum target,
3222 GLint level,
3223 GLint internalformat,
3224 GLsizei width,
3225 GLsizei height,
3226 GLsizei depth,
3227 GLint border,
3228 GLenum format,
3229 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003230 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003231{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003232 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003233
3234 Extents size(width, height, depth);
3235 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003236 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3237 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003238}
3239
3240void Context::texSubImage2D(GLenum target,
3241 GLint level,
3242 GLint xoffset,
3243 GLint yoffset,
3244 GLsizei width,
3245 GLsizei height,
3246 GLenum format,
3247 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003248 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003249{
3250 // Zero sized uploads are valid but no-ops
3251 if (width == 0 || height == 0)
3252 {
3253 return;
3254 }
3255
Jamie Madillad9f24e2016-02-12 09:27:24 -05003256 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003257
3258 Box area(xoffset, yoffset, 0, width, height, 1);
3259 Texture *texture =
3260 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003261 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3262 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003263}
3264
3265void Context::texSubImage3D(GLenum target,
3266 GLint level,
3267 GLint xoffset,
3268 GLint yoffset,
3269 GLint zoffset,
3270 GLsizei width,
3271 GLsizei height,
3272 GLsizei depth,
3273 GLenum format,
3274 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003275 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003276{
3277 // Zero sized uploads are valid but no-ops
3278 if (width == 0 || height == 0 || depth == 0)
3279 {
3280 return;
3281 }
3282
Jamie Madillad9f24e2016-02-12 09:27:24 -05003283 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003284
3285 Box area(xoffset, yoffset, zoffset, width, height, depth);
3286 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003287 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3288 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003289}
3290
3291void Context::compressedTexImage2D(GLenum target,
3292 GLint level,
3293 GLenum internalformat,
3294 GLsizei width,
3295 GLsizei height,
3296 GLint border,
3297 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003298 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003299{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003300 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003301
3302 Extents size(width, height, 1);
3303 Texture *texture =
3304 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003305 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003306 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003307 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003308}
3309
3310void Context::compressedTexImage3D(GLenum target,
3311 GLint level,
3312 GLenum internalformat,
3313 GLsizei width,
3314 GLsizei height,
3315 GLsizei depth,
3316 GLint border,
3317 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003318 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003319{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003320 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003321
3322 Extents size(width, height, depth);
3323 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003324 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003325 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003326 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003327}
3328
3329void Context::compressedTexSubImage2D(GLenum target,
3330 GLint level,
3331 GLint xoffset,
3332 GLint yoffset,
3333 GLsizei width,
3334 GLsizei height,
3335 GLenum format,
3336 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003337 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003338{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003339 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003340
3341 Box area(xoffset, yoffset, 0, width, height, 1);
3342 Texture *texture =
3343 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003344 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003345 format, imageSize,
3346 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003347}
3348
3349void Context::compressedTexSubImage3D(GLenum target,
3350 GLint level,
3351 GLint xoffset,
3352 GLint yoffset,
3353 GLint zoffset,
3354 GLsizei width,
3355 GLsizei height,
3356 GLsizei depth,
3357 GLenum format,
3358 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003359 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003360{
3361 // Zero sized uploads are valid but no-ops
3362 if (width == 0 || height == 0)
3363 {
3364 return;
3365 }
3366
Jamie Madillad9f24e2016-02-12 09:27:24 -05003367 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003368
3369 Box area(xoffset, yoffset, zoffset, width, height, depth);
3370 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003371 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003372 format, imageSize,
3373 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003374}
3375
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003376void Context::generateMipmap(GLenum target)
3377{
3378 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003379 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003380}
3381
Geoff Lang97073d12016-04-20 10:42:34 -07003382void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003383 GLint sourceLevel,
3384 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003385 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003386 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003387 GLint internalFormat,
3388 GLenum destType,
3389 GLboolean unpackFlipY,
3390 GLboolean unpackPremultiplyAlpha,
3391 GLboolean unpackUnmultiplyAlpha)
3392{
3393 syncStateForTexImage();
3394
3395 gl::Texture *sourceTexture = getTexture(sourceId);
3396 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003397 handleError(destTexture->copyTexture(
3398 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3399 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003400}
3401
3402void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003403 GLint sourceLevel,
3404 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003405 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003406 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003407 GLint xoffset,
3408 GLint yoffset,
3409 GLint x,
3410 GLint y,
3411 GLsizei width,
3412 GLsizei height,
3413 GLboolean unpackFlipY,
3414 GLboolean unpackPremultiplyAlpha,
3415 GLboolean unpackUnmultiplyAlpha)
3416{
3417 // Zero sized copies are valid but no-ops
3418 if (width == 0 || height == 0)
3419 {
3420 return;
3421 }
3422
3423 syncStateForTexImage();
3424
3425 gl::Texture *sourceTexture = getTexture(sourceId);
3426 gl::Texture *destTexture = getTexture(destId);
3427 Offset offset(xoffset, yoffset, 0);
3428 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003429 handleError(destTexture->copySubTexture(
3430 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3431 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003432}
3433
Geoff Lang47110bf2016-04-20 11:13:22 -07003434void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3435{
3436 syncStateForTexImage();
3437
3438 gl::Texture *sourceTexture = getTexture(sourceId);
3439 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003440 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003441}
3442
Geoff Lang496c02d2016-10-20 11:38:11 -07003443void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003444{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003445 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003446 ASSERT(buffer);
3447
Geoff Lang496c02d2016-10-20 11:38:11 -07003448 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003449}
3450
Jamie Madill876429b2017-04-20 15:46:24 -04003451void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003452{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003453 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003454 ASSERT(buffer);
3455
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003456 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003457 if (error.isError())
3458 {
Jamie Madill437fa652016-05-03 15:13:24 -04003459 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003460 return nullptr;
3461 }
3462
3463 return buffer->getMapPointer();
3464}
3465
3466GLboolean Context::unmapBuffer(GLenum target)
3467{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003468 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003469 ASSERT(buffer);
3470
3471 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003472 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003473 if (error.isError())
3474 {
Jamie Madill437fa652016-05-03 15:13:24 -04003475 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003476 return GL_FALSE;
3477 }
3478
3479 return result;
3480}
3481
Jamie Madill876429b2017-04-20 15:46:24 -04003482void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003483{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003484 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003485 ASSERT(buffer);
3486
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003487 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003488 if (error.isError())
3489 {
Jamie Madill437fa652016-05-03 15:13:24 -04003490 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003491 return nullptr;
3492 }
3493
3494 return buffer->getMapPointer();
3495}
3496
3497void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3498{
3499 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3500}
3501
Jamie Madillad9f24e2016-02-12 09:27:24 -05003502void Context::syncStateForReadPixels()
3503{
3504 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3505}
3506
3507void Context::syncStateForTexImage()
3508{
3509 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3510}
3511
3512void Context::syncStateForClear()
3513{
3514 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3515}
3516
3517void Context::syncStateForBlit()
3518{
3519 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3520}
3521
Jamie Madillc20ab272016-06-09 07:20:46 -07003522void Context::activeTexture(GLenum texture)
3523{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003524 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003525}
3526
Jamie Madill876429b2017-04-20 15:46:24 -04003527void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003530}
3531
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003532void Context::blendEquation(GLenum mode)
3533{
3534 mGLState.setBlendEquation(mode, mode);
3535}
3536
Jamie Madillc20ab272016-06-09 07:20:46 -07003537void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3538{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003539 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003540}
3541
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003542void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3543{
3544 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3545}
3546
Jamie Madillc20ab272016-06-09 07:20:46 -07003547void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003550}
3551
Jamie Madill876429b2017-04-20 15:46:24 -04003552void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003553{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003554 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003555}
3556
Jamie Madill876429b2017-04-20 15:46:24 -04003557void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003558{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003559 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003560}
3561
3562void Context::clearStencil(GLint s)
3563{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003564 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003565}
3566
3567void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3568{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003569 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003570}
3571
3572void Context::cullFace(GLenum mode)
3573{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003574 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003575}
3576
3577void Context::depthFunc(GLenum func)
3578{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003579 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003580}
3581
3582void Context::depthMask(GLboolean flag)
3583{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003584 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003585}
3586
Jamie Madill876429b2017-04-20 15:46:24 -04003587void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003588{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003589 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003590}
3591
3592void Context::disable(GLenum cap)
3593{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003594 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003595}
3596
3597void Context::disableVertexAttribArray(GLuint index)
3598{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003599 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003600}
3601
3602void Context::enable(GLenum cap)
3603{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003604 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003605}
3606
3607void Context::enableVertexAttribArray(GLuint index)
3608{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003609 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003610}
3611
3612void Context::frontFace(GLenum mode)
3613{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003614 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003615}
3616
3617void Context::hint(GLenum target, GLenum mode)
3618{
3619 switch (target)
3620 {
3621 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003622 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003623 break;
3624
3625 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003626 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003627 break;
3628
3629 default:
3630 UNREACHABLE();
3631 return;
3632 }
3633}
3634
3635void Context::lineWidth(GLfloat width)
3636{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003637 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003638}
3639
3640void Context::pixelStorei(GLenum pname, GLint param)
3641{
3642 switch (pname)
3643 {
3644 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003645 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003646 break;
3647
3648 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003649 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003650 break;
3651
3652 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003653 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003654 break;
3655
3656 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003657 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003658 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003659 break;
3660
3661 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003662 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003663 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003664 break;
3665
3666 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003667 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003668 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003669 break;
3670
3671 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003672 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003673 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003674 break;
3675
3676 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003677 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003678 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003679 break;
3680
3681 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003682 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003683 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003684 break;
3685
3686 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003687 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003688 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003689 break;
3690
3691 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003692 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003693 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003694 break;
3695
3696 default:
3697 UNREACHABLE();
3698 return;
3699 }
3700}
3701
3702void Context::polygonOffset(GLfloat factor, GLfloat units)
3703{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003704 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003705}
3706
Jamie Madill876429b2017-04-20 15:46:24 -04003707void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003708{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003709 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003710}
3711
3712void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3713{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003714 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003715}
3716
3717void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3718{
3719 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3720 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003721 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003722 }
3723
3724 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3725 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003726 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003727 }
3728}
3729
3730void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3731{
3732 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3733 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003734 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003735 }
3736
3737 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3738 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003739 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003740 }
3741}
3742
3743void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3744{
3745 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3746 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003747 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003748 }
3749
3750 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3751 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003752 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003753 }
3754}
3755
3756void Context::vertexAttrib1f(GLuint index, GLfloat x)
3757{
3758 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003759 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003760}
3761
3762void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3763{
3764 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003765 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003766}
3767
3768void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3769{
3770 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003771 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003772}
3773
3774void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3775{
3776 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003777 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003778}
3779
3780void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3781{
3782 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003783 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003784}
3785
3786void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3787{
3788 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003789 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003790}
3791
3792void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3793{
3794 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003795 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003796}
3797
3798void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3799{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003800 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003801}
3802
3803void Context::vertexAttribPointer(GLuint index,
3804 GLint size,
3805 GLenum type,
3806 GLboolean normalized,
3807 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003808 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003809{
Shaodde78e82017-05-22 14:13:27 +08003810 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3811 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003812}
3813
Shao80957d92017-02-20 21:25:59 +08003814void Context::vertexAttribFormat(GLuint attribIndex,
3815 GLint size,
3816 GLenum type,
3817 GLboolean normalized,
3818 GLuint relativeOffset)
3819{
3820 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3821 relativeOffset);
3822}
3823
3824void Context::vertexAttribIFormat(GLuint attribIndex,
3825 GLint size,
3826 GLenum type,
3827 GLuint relativeOffset)
3828{
3829 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3830}
3831
3832void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3833{
Shaodde78e82017-05-22 14:13:27 +08003834 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003835}
3836
3837void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3838{
3839 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3840}
3841
Jamie Madillc20ab272016-06-09 07:20:46 -07003842void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3843{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003844 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003845}
3846
3847void Context::vertexAttribIPointer(GLuint index,
3848 GLint size,
3849 GLenum type,
3850 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003851 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003852{
Shaodde78e82017-05-22 14:13:27 +08003853 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3854 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003855}
3856
3857void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3858{
3859 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003860 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003861}
3862
3863void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3864{
3865 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003866 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003867}
3868
3869void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3870{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003871 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003872}
3873
3874void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3875{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003876 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003877}
3878
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003879void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3880{
3881 const VertexAttribCurrentValueData &currentValues =
3882 getGLState().getVertexAttribCurrentValue(index);
3883 const VertexArray *vao = getGLState().getVertexArray();
3884 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3885 currentValues, pname, params);
3886}
3887
3888void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3889{
3890 const VertexAttribCurrentValueData &currentValues =
3891 getGLState().getVertexAttribCurrentValue(index);
3892 const VertexArray *vao = getGLState().getVertexArray();
3893 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3894 currentValues, pname, params);
3895}
3896
3897void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3898{
3899 const VertexAttribCurrentValueData &currentValues =
3900 getGLState().getVertexAttribCurrentValue(index);
3901 const VertexArray *vao = getGLState().getVertexArray();
3902 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3903 currentValues, pname, params);
3904}
3905
3906void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3907{
3908 const VertexAttribCurrentValueData &currentValues =
3909 getGLState().getVertexAttribCurrentValue(index);
3910 const VertexArray *vao = getGLState().getVertexArray();
3911 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3912 currentValues, pname, params);
3913}
3914
Jamie Madill876429b2017-04-20 15:46:24 -04003915void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003916{
3917 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3918 QueryVertexAttribPointerv(attrib, pname, pointer);
3919}
3920
Jamie Madillc20ab272016-06-09 07:20:46 -07003921void Context::debugMessageControl(GLenum source,
3922 GLenum type,
3923 GLenum severity,
3924 GLsizei count,
3925 const GLuint *ids,
3926 GLboolean enabled)
3927{
3928 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003929 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3930 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003931}
3932
3933void Context::debugMessageInsert(GLenum source,
3934 GLenum type,
3935 GLuint id,
3936 GLenum severity,
3937 GLsizei length,
3938 const GLchar *buf)
3939{
3940 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003941 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003942}
3943
3944void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3945{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003946 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003947}
3948
3949GLuint Context::getDebugMessageLog(GLuint count,
3950 GLsizei bufSize,
3951 GLenum *sources,
3952 GLenum *types,
3953 GLuint *ids,
3954 GLenum *severities,
3955 GLsizei *lengths,
3956 GLchar *messageLog)
3957{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003958 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3959 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003960}
3961
3962void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3963{
3964 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003965 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003966}
3967
3968void Context::popDebugGroup()
3969{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003970 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003971}
3972
Jamie Madill876429b2017-04-20 15:46:24 -04003973void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003974{
3975 Buffer *buffer = mGLState.getTargetBuffer(target);
3976 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003977 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003978}
3979
Jamie Madill876429b2017-04-20 15:46:24 -04003980void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003981{
3982 if (data == nullptr)
3983 {
3984 return;
3985 }
3986
3987 Buffer *buffer = mGLState.getTargetBuffer(target);
3988 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003989 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003990}
3991
Jamie Madillef300b12016-10-07 15:12:09 -04003992void Context::attachShader(GLuint program, GLuint shader)
3993{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003994 auto programObject = mState.mShaderPrograms->getProgram(program);
3995 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003996 ASSERT(programObject && shaderObject);
3997 programObject->attachShader(shaderObject);
3998}
3999
Kenneth Russellf2f6f652016-10-05 19:53:23 -07004000const Workarounds &Context::getWorkarounds() const
4001{
4002 return mWorkarounds;
4003}
4004
Jamie Madillb0817d12016-11-01 15:48:31 -04004005void Context::copyBufferSubData(GLenum readTarget,
4006 GLenum writeTarget,
4007 GLintptr readOffset,
4008 GLintptr writeOffset,
4009 GLsizeiptr size)
4010{
4011 // if size is zero, the copy is a successful no-op
4012 if (size == 0)
4013 {
4014 return;
4015 }
4016
4017 // TODO(jmadill): cache these.
4018 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
4019 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
4020
Jamie Madill5f56ddb2017-01-13 17:29:55 -05004021 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04004022}
4023
Jamie Madill01a80ee2016-11-07 12:06:18 -05004024void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
4025{
4026 Program *programObject = getProgram(program);
4027 // TODO(jmadill): Re-use this from the validation if possible.
4028 ASSERT(programObject);
4029 programObject->bindAttributeLocation(index, name);
4030}
4031
4032void Context::bindBuffer(GLenum target, GLuint buffer)
4033{
4034 switch (target)
4035 {
4036 case GL_ARRAY_BUFFER:
4037 bindArrayBuffer(buffer);
4038 break;
4039 case GL_ELEMENT_ARRAY_BUFFER:
4040 bindElementArrayBuffer(buffer);
4041 break;
4042 case GL_COPY_READ_BUFFER:
4043 bindCopyReadBuffer(buffer);
4044 break;
4045 case GL_COPY_WRITE_BUFFER:
4046 bindCopyWriteBuffer(buffer);
4047 break;
4048 case GL_PIXEL_PACK_BUFFER:
4049 bindPixelPackBuffer(buffer);
4050 break;
4051 case GL_PIXEL_UNPACK_BUFFER:
4052 bindPixelUnpackBuffer(buffer);
4053 break;
4054 case GL_UNIFORM_BUFFER:
4055 bindGenericUniformBuffer(buffer);
4056 break;
4057 case GL_TRANSFORM_FEEDBACK_BUFFER:
4058 bindGenericTransformFeedbackBuffer(buffer);
4059 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004060 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004061 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004062 break;
4063 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004064 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004065 break;
4066 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004067 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004068 break;
4069 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004070 if (buffer != 0)
4071 {
4072 // Binding buffers to this binding point is not implemented yet.
4073 UNIMPLEMENTED();
4074 }
Geoff Lang3b573612016-10-31 14:08:10 -04004075 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004076
4077 default:
4078 UNREACHABLE();
4079 break;
4080 }
4081}
4082
Jiajia Qin6eafb042016-12-27 17:04:07 +08004083void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4084{
4085 bindBufferRange(target, index, buffer, 0, 0);
4086}
4087
4088void Context::bindBufferRange(GLenum target,
4089 GLuint index,
4090 GLuint buffer,
4091 GLintptr offset,
4092 GLsizeiptr size)
4093{
4094 switch (target)
4095 {
4096 case GL_TRANSFORM_FEEDBACK_BUFFER:
4097 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4098 bindGenericTransformFeedbackBuffer(buffer);
4099 break;
4100 case GL_UNIFORM_BUFFER:
4101 bindIndexedUniformBuffer(buffer, index, offset, size);
4102 bindGenericUniformBuffer(buffer);
4103 break;
4104 case GL_ATOMIC_COUNTER_BUFFER:
4105 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4106 bindGenericAtomicCounterBuffer(buffer);
4107 break;
4108 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004109 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4110 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004111 break;
4112 default:
4113 UNREACHABLE();
4114 break;
4115 }
4116}
4117
Jamie Madill01a80ee2016-11-07 12:06:18 -05004118void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4119{
4120 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4121 {
4122 bindReadFramebuffer(framebuffer);
4123 }
4124
4125 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4126 {
4127 bindDrawFramebuffer(framebuffer);
4128 }
4129}
4130
4131void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4132{
4133 ASSERT(target == GL_RENDERBUFFER);
4134 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004135 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004136 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004137}
4138
JiangYizhoubddc46b2016-12-09 09:50:51 +08004139void Context::texStorage2DMultisample(GLenum target,
4140 GLsizei samples,
4141 GLenum internalformat,
4142 GLsizei width,
4143 GLsizei height,
4144 GLboolean fixedsamplelocations)
4145{
4146 Extents size(width, height, 1);
4147 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004148 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004149 fixedsamplelocations));
4150}
4151
4152void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4153{
JiangYizhou5b03f472017-01-09 10:22:53 +08004154 // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
4155 // the sample position should be queried by DRAW_FRAMEBUFFER.
4156 mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER);
4157 const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
JiangYizhoubddc46b2016-12-09 09:50:51 +08004158
4159 switch (pname)
4160 {
4161 case GL_SAMPLE_POSITION:
4162 handleError(framebuffer->getSamplePosition(index, val));
4163 break;
4164 default:
4165 UNREACHABLE();
4166 }
4167}
4168
Jamie Madille8fb6402017-02-14 17:56:40 -05004169void Context::renderbufferStorage(GLenum target,
4170 GLenum internalformat,
4171 GLsizei width,
4172 GLsizei height)
4173{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004174 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4175 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4176
Jamie Madille8fb6402017-02-14 17:56:40 -05004177 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004178 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004179}
4180
4181void Context::renderbufferStorageMultisample(GLenum target,
4182 GLsizei samples,
4183 GLenum internalformat,
4184 GLsizei width,
4185 GLsizei height)
4186{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004187 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4188 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004189
4190 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004191 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004192 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004193}
4194
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004195void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4196{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004197 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004198 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004199}
4200
JiangYizhoue18e6392017-02-20 10:32:23 +08004201void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4202{
4203 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4204 QueryFramebufferParameteriv(framebuffer, pname, params);
4205}
4206
4207void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4208{
4209 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4210 SetFramebufferParameteri(framebuffer, pname, param);
4211}
4212
Jamie Madillb3f26b92017-07-19 15:07:41 -04004213Error Context::getScratchBuffer(size_t requstedSizeBytes,
4214 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004215{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004216 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4217 {
4218 return OutOfMemory() << "Failed to allocate internal buffer.";
4219 }
4220 return NoError();
4221}
4222
4223Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4224 angle::MemoryBuffer **zeroBufferOut) const
4225{
4226 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004227 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004228 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004229 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004230 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004231}
4232
Xinghua Cao2b396592017-03-29 15:36:04 +08004233void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4234{
4235 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4236 {
4237 return;
4238 }
4239
Jamie Madill71c88b32017-09-14 22:20:29 -04004240 handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
Xinghua Cao2b396592017-03-29 15:36:04 +08004241}
4242
JiangYizhou165361c2017-06-07 14:56:57 +08004243void Context::texStorage2D(GLenum target,
4244 GLsizei levels,
4245 GLenum internalFormat,
4246 GLsizei width,
4247 GLsizei height)
4248{
4249 Extents size(width, height, 1);
4250 Texture *texture = getTargetTexture(target);
4251 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4252}
4253
4254void Context::texStorage3D(GLenum target,
4255 GLsizei levels,
4256 GLenum internalFormat,
4257 GLsizei width,
4258 GLsizei height,
4259 GLsizei depth)
4260{
4261 Extents size(width, height, depth);
4262 Texture *texture = getTargetTexture(target);
4263 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4264}
4265
Jamie Madillc1d770e2017-04-13 17:31:24 -04004266GLenum Context::checkFramebufferStatus(GLenum target)
4267{
4268 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4269 ASSERT(framebuffer);
4270
4271 return framebuffer->checkStatus(this);
4272}
4273
4274void Context::compileShader(GLuint shader)
4275{
4276 Shader *shaderObject = GetValidShader(this, shader);
4277 if (!shaderObject)
4278 {
4279 return;
4280 }
4281 shaderObject->compile(this);
4282}
4283
4284void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4285{
4286 for (int i = 0; i < n; i++)
4287 {
4288 deleteBuffer(buffers[i]);
4289 }
4290}
4291
4292void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4293{
4294 for (int i = 0; i < n; i++)
4295 {
4296 if (framebuffers[i] != 0)
4297 {
4298 deleteFramebuffer(framebuffers[i]);
4299 }
4300 }
4301}
4302
4303void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4304{
4305 for (int i = 0; i < n; i++)
4306 {
4307 deleteRenderbuffer(renderbuffers[i]);
4308 }
4309}
4310
4311void Context::deleteTextures(GLsizei n, const GLuint *textures)
4312{
4313 for (int i = 0; i < n; i++)
4314 {
4315 if (textures[i] != 0)
4316 {
4317 deleteTexture(textures[i]);
4318 }
4319 }
4320}
4321
4322void Context::detachShader(GLuint program, GLuint shader)
4323{
4324 Program *programObject = getProgram(program);
4325 ASSERT(programObject);
4326
4327 Shader *shaderObject = getShader(shader);
4328 ASSERT(shaderObject);
4329
4330 programObject->detachShader(this, shaderObject);
4331}
4332
4333void Context::genBuffers(GLsizei n, GLuint *buffers)
4334{
4335 for (int i = 0; i < n; i++)
4336 {
4337 buffers[i] = createBuffer();
4338 }
4339}
4340
4341void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4342{
4343 for (int i = 0; i < n; i++)
4344 {
4345 framebuffers[i] = createFramebuffer();
4346 }
4347}
4348
4349void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4350{
4351 for (int i = 0; i < n; i++)
4352 {
4353 renderbuffers[i] = createRenderbuffer();
4354 }
4355}
4356
4357void Context::genTextures(GLsizei n, GLuint *textures)
4358{
4359 for (int i = 0; i < n; i++)
4360 {
4361 textures[i] = createTexture();
4362 }
4363}
4364
4365void Context::getActiveAttrib(GLuint program,
4366 GLuint index,
4367 GLsizei bufsize,
4368 GLsizei *length,
4369 GLint *size,
4370 GLenum *type,
4371 GLchar *name)
4372{
4373 Program *programObject = getProgram(program);
4374 ASSERT(programObject);
4375 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4376}
4377
4378void Context::getActiveUniform(GLuint program,
4379 GLuint index,
4380 GLsizei bufsize,
4381 GLsizei *length,
4382 GLint *size,
4383 GLenum *type,
4384 GLchar *name)
4385{
4386 Program *programObject = getProgram(program);
4387 ASSERT(programObject);
4388 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4389}
4390
4391void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4392{
4393 Program *programObject = getProgram(program);
4394 ASSERT(programObject);
4395 programObject->getAttachedShaders(maxcount, count, shaders);
4396}
4397
4398GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4399{
4400 Program *programObject = getProgram(program);
4401 ASSERT(programObject);
4402 return programObject->getAttributeLocation(name);
4403}
4404
4405void Context::getBooleanv(GLenum pname, GLboolean *params)
4406{
4407 GLenum nativeType;
4408 unsigned int numParams = 0;
4409 getQueryParameterInfo(pname, &nativeType, &numParams);
4410
4411 if (nativeType == GL_BOOL)
4412 {
4413 getBooleanvImpl(pname, params);
4414 }
4415 else
4416 {
4417 CastStateValues(this, nativeType, pname, numParams, params);
4418 }
4419}
4420
4421void Context::getFloatv(GLenum pname, GLfloat *params)
4422{
4423 GLenum nativeType;
4424 unsigned int numParams = 0;
4425 getQueryParameterInfo(pname, &nativeType, &numParams);
4426
4427 if (nativeType == GL_FLOAT)
4428 {
4429 getFloatvImpl(pname, params);
4430 }
4431 else
4432 {
4433 CastStateValues(this, nativeType, pname, numParams, params);
4434 }
4435}
4436
4437void Context::getIntegerv(GLenum pname, GLint *params)
4438{
4439 GLenum nativeType;
4440 unsigned int numParams = 0;
4441 getQueryParameterInfo(pname, &nativeType, &numParams);
4442
4443 if (nativeType == GL_INT)
4444 {
4445 getIntegervImpl(pname, params);
4446 }
4447 else
4448 {
4449 CastStateValues(this, nativeType, pname, numParams, params);
4450 }
4451}
4452
4453void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4454{
4455 Program *programObject = getProgram(program);
4456 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004457 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004458}
4459
Jamie Madillbe849e42017-05-02 15:49:00 -04004460void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004461{
4462 Program *programObject = getProgram(program);
4463 ASSERT(programObject);
4464 programObject->getInfoLog(bufsize, length, infolog);
4465}
4466
4467void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4468{
4469 Shader *shaderObject = getShader(shader);
4470 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004471 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004472}
4473
4474void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4475{
4476 Shader *shaderObject = getShader(shader);
4477 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004478 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004479}
4480
4481void Context::getShaderPrecisionFormat(GLenum shadertype,
4482 GLenum precisiontype,
4483 GLint *range,
4484 GLint *precision)
4485{
4486 // TODO(jmadill): Compute shaders.
4487
4488 switch (shadertype)
4489 {
4490 case GL_VERTEX_SHADER:
4491 switch (precisiontype)
4492 {
4493 case GL_LOW_FLOAT:
4494 mCaps.vertexLowpFloat.get(range, precision);
4495 break;
4496 case GL_MEDIUM_FLOAT:
4497 mCaps.vertexMediumpFloat.get(range, precision);
4498 break;
4499 case GL_HIGH_FLOAT:
4500 mCaps.vertexHighpFloat.get(range, precision);
4501 break;
4502
4503 case GL_LOW_INT:
4504 mCaps.vertexLowpInt.get(range, precision);
4505 break;
4506 case GL_MEDIUM_INT:
4507 mCaps.vertexMediumpInt.get(range, precision);
4508 break;
4509 case GL_HIGH_INT:
4510 mCaps.vertexHighpInt.get(range, precision);
4511 break;
4512
4513 default:
4514 UNREACHABLE();
4515 return;
4516 }
4517 break;
4518
4519 case GL_FRAGMENT_SHADER:
4520 switch (precisiontype)
4521 {
4522 case GL_LOW_FLOAT:
4523 mCaps.fragmentLowpFloat.get(range, precision);
4524 break;
4525 case GL_MEDIUM_FLOAT:
4526 mCaps.fragmentMediumpFloat.get(range, precision);
4527 break;
4528 case GL_HIGH_FLOAT:
4529 mCaps.fragmentHighpFloat.get(range, precision);
4530 break;
4531
4532 case GL_LOW_INT:
4533 mCaps.fragmentLowpInt.get(range, precision);
4534 break;
4535 case GL_MEDIUM_INT:
4536 mCaps.fragmentMediumpInt.get(range, precision);
4537 break;
4538 case GL_HIGH_INT:
4539 mCaps.fragmentHighpInt.get(range, precision);
4540 break;
4541
4542 default:
4543 UNREACHABLE();
4544 return;
4545 }
4546 break;
4547
4548 default:
4549 UNREACHABLE();
4550 return;
4551 }
4552}
4553
4554void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4555{
4556 Shader *shaderObject = getShader(shader);
4557 ASSERT(shaderObject);
4558 shaderObject->getSource(bufsize, length, source);
4559}
4560
4561void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4562{
4563 Program *programObject = getProgram(program);
4564 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004565 programObject->getUniformfv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004566}
4567
4568void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4569{
4570 Program *programObject = getProgram(program);
4571 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004572 programObject->getUniformiv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004573}
4574
4575GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4576{
4577 Program *programObject = getProgram(program);
4578 ASSERT(programObject);
4579 return programObject->getUniformLocation(name);
4580}
4581
4582GLboolean Context::isBuffer(GLuint buffer)
4583{
4584 if (buffer == 0)
4585 {
4586 return GL_FALSE;
4587 }
4588
4589 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4590}
4591
4592GLboolean Context::isEnabled(GLenum cap)
4593{
4594 return mGLState.getEnableFeature(cap);
4595}
4596
4597GLboolean Context::isFramebuffer(GLuint framebuffer)
4598{
4599 if (framebuffer == 0)
4600 {
4601 return GL_FALSE;
4602 }
4603
4604 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4605}
4606
4607GLboolean Context::isProgram(GLuint program)
4608{
4609 if (program == 0)
4610 {
4611 return GL_FALSE;
4612 }
4613
4614 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4615}
4616
4617GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4618{
4619 if (renderbuffer == 0)
4620 {
4621 return GL_FALSE;
4622 }
4623
4624 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4625}
4626
4627GLboolean Context::isShader(GLuint shader)
4628{
4629 if (shader == 0)
4630 {
4631 return GL_FALSE;
4632 }
4633
4634 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4635}
4636
4637GLboolean Context::isTexture(GLuint texture)
4638{
4639 if (texture == 0)
4640 {
4641 return GL_FALSE;
4642 }
4643
4644 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4645}
4646
4647void Context::linkProgram(GLuint program)
4648{
4649 Program *programObject = getProgram(program);
4650 ASSERT(programObject);
4651 handleError(programObject->link(this));
Martin Radev0abb7a22017-08-28 15:34:45 +03004652 mGLState.onProgramExecutableChange(programObject);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004653}
4654
4655void Context::releaseShaderCompiler()
4656{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004657 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004658}
4659
4660void Context::shaderBinary(GLsizei n,
4661 const GLuint *shaders,
4662 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004663 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004664 GLsizei length)
4665{
4666 // No binary shader formats are supported.
4667 UNIMPLEMENTED();
4668}
4669
4670void Context::shaderSource(GLuint shader,
4671 GLsizei count,
4672 const GLchar *const *string,
4673 const GLint *length)
4674{
4675 Shader *shaderObject = getShader(shader);
4676 ASSERT(shaderObject);
4677 shaderObject->setSource(count, string, length);
4678}
4679
4680void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4681{
4682 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4683}
4684
4685void Context::stencilMask(GLuint mask)
4686{
4687 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4688}
4689
4690void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4691{
4692 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4693}
4694
4695void Context::uniform1f(GLint location, GLfloat x)
4696{
4697 Program *program = mGLState.getProgram();
4698 program->setUniform1fv(location, 1, &x);
4699}
4700
4701void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4702{
4703 Program *program = mGLState.getProgram();
4704 program->setUniform1fv(location, count, v);
4705}
4706
4707void Context::uniform1i(GLint location, GLint x)
4708{
4709 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004710 if (program->setUniform1iv(location, 1, &x) == Program::SetUniformResult::SamplerChanged)
4711 {
4712 mGLState.setObjectDirty(GL_PROGRAM);
4713 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004714}
4715
4716void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4717{
4718 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004719 if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged)
4720 {
4721 mGLState.setObjectDirty(GL_PROGRAM);
4722 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004723}
4724
4725void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4726{
4727 GLfloat xy[2] = {x, y};
4728 Program *program = mGLState.getProgram();
4729 program->setUniform2fv(location, 1, xy);
4730}
4731
4732void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4733{
4734 Program *program = mGLState.getProgram();
4735 program->setUniform2fv(location, count, v);
4736}
4737
4738void Context::uniform2i(GLint location, GLint x, GLint y)
4739{
4740 GLint xy[2] = {x, y};
4741 Program *program = mGLState.getProgram();
4742 program->setUniform2iv(location, 1, xy);
4743}
4744
4745void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4746{
4747 Program *program = mGLState.getProgram();
4748 program->setUniform2iv(location, count, v);
4749}
4750
4751void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4752{
4753 GLfloat xyz[3] = {x, y, z};
4754 Program *program = mGLState.getProgram();
4755 program->setUniform3fv(location, 1, xyz);
4756}
4757
4758void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4759{
4760 Program *program = mGLState.getProgram();
4761 program->setUniform3fv(location, count, v);
4762}
4763
4764void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4765{
4766 GLint xyz[3] = {x, y, z};
4767 Program *program = mGLState.getProgram();
4768 program->setUniform3iv(location, 1, xyz);
4769}
4770
4771void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4772{
4773 Program *program = mGLState.getProgram();
4774 program->setUniform3iv(location, count, v);
4775}
4776
4777void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4778{
4779 GLfloat xyzw[4] = {x, y, z, w};
4780 Program *program = mGLState.getProgram();
4781 program->setUniform4fv(location, 1, xyzw);
4782}
4783
4784void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4785{
4786 Program *program = mGLState.getProgram();
4787 program->setUniform4fv(location, count, v);
4788}
4789
4790void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4791{
4792 GLint xyzw[4] = {x, y, z, w};
4793 Program *program = mGLState.getProgram();
4794 program->setUniform4iv(location, 1, xyzw);
4795}
4796
4797void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4798{
4799 Program *program = mGLState.getProgram();
4800 program->setUniform4iv(location, count, v);
4801}
4802
4803void Context::uniformMatrix2fv(GLint location,
4804 GLsizei count,
4805 GLboolean transpose,
4806 const GLfloat *value)
4807{
4808 Program *program = mGLState.getProgram();
4809 program->setUniformMatrix2fv(location, count, transpose, value);
4810}
4811
4812void Context::uniformMatrix3fv(GLint location,
4813 GLsizei count,
4814 GLboolean transpose,
4815 const GLfloat *value)
4816{
4817 Program *program = mGLState.getProgram();
4818 program->setUniformMatrix3fv(location, count, transpose, value);
4819}
4820
4821void Context::uniformMatrix4fv(GLint location,
4822 GLsizei count,
4823 GLboolean transpose,
4824 const GLfloat *value)
4825{
4826 Program *program = mGLState.getProgram();
4827 program->setUniformMatrix4fv(location, count, transpose, value);
4828}
4829
4830void Context::validateProgram(GLuint program)
4831{
4832 Program *programObject = getProgram(program);
4833 ASSERT(programObject);
4834 programObject->validate(mCaps);
4835}
4836
Jamie Madilld04908b2017-06-09 14:15:35 -04004837void Context::getProgramBinary(GLuint program,
4838 GLsizei bufSize,
4839 GLsizei *length,
4840 GLenum *binaryFormat,
4841 void *binary)
4842{
4843 Program *programObject = getProgram(program);
4844 ASSERT(programObject != nullptr);
4845
4846 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4847}
4848
4849void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4850{
4851 Program *programObject = getProgram(program);
4852 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004853
Jamie Madilld04908b2017-06-09 14:15:35 -04004854 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4855}
4856
Jamie Madillff325f12017-08-26 15:06:05 -04004857void Context::uniform1ui(GLint location, GLuint v0)
4858{
4859 Program *program = mGLState.getProgram();
4860 program->setUniform1uiv(location, 1, &v0);
4861}
4862
4863void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4864{
4865 Program *program = mGLState.getProgram();
4866 const GLuint xy[] = {v0, v1};
4867 program->setUniform2uiv(location, 1, xy);
4868}
4869
4870void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4871{
4872 Program *program = mGLState.getProgram();
4873 const GLuint xyz[] = {v0, v1, v2};
4874 program->setUniform3uiv(location, 1, xyz);
4875}
4876
4877void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4878{
4879 Program *program = mGLState.getProgram();
4880 const GLuint xyzw[] = {v0, v1, v2, v3};
4881 program->setUniform4uiv(location, 1, xyzw);
4882}
4883
4884void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4885{
4886 Program *program = mGLState.getProgram();
4887 program->setUniform1uiv(location, count, value);
4888}
4889void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4890{
4891 Program *program = mGLState.getProgram();
4892 program->setUniform2uiv(location, count, value);
4893}
4894
4895void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4896{
4897 Program *program = mGLState.getProgram();
4898 program->setUniform3uiv(location, count, value);
4899}
4900
4901void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4902{
4903 Program *program = mGLState.getProgram();
4904 program->setUniform4uiv(location, count, value);
4905}
4906
Jamie Madillf0e04492017-08-26 15:28:42 -04004907void Context::genQueries(GLsizei n, GLuint *ids)
4908{
4909 for (GLsizei i = 0; i < n; i++)
4910 {
4911 GLuint handle = mQueryHandleAllocator.allocate();
4912 mQueryMap.assign(handle, nullptr);
4913 ids[i] = handle;
4914 }
4915}
4916
4917void Context::deleteQueries(GLsizei n, const GLuint *ids)
4918{
4919 for (int i = 0; i < n; i++)
4920 {
4921 GLuint query = ids[i];
4922
4923 Query *queryObject = nullptr;
4924 if (mQueryMap.erase(query, &queryObject))
4925 {
4926 mQueryHandleAllocator.release(query);
4927 if (queryObject)
4928 {
4929 queryObject->release(this);
4930 }
4931 }
4932 }
4933}
4934
4935GLboolean Context::isQuery(GLuint id)
4936{
4937 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4938}
4939
Jamie Madillc8c95812017-08-26 18:40:09 -04004940void Context::uniformMatrix2x3fv(GLint location,
4941 GLsizei count,
4942 GLboolean transpose,
4943 const GLfloat *value)
4944{
4945 Program *program = mGLState.getProgram();
4946 program->setUniformMatrix2x3fv(location, count, transpose, value);
4947}
4948
4949void Context::uniformMatrix3x2fv(GLint location,
4950 GLsizei count,
4951 GLboolean transpose,
4952 const GLfloat *value)
4953{
4954 Program *program = mGLState.getProgram();
4955 program->setUniformMatrix3x2fv(location, count, transpose, value);
4956}
4957
4958void Context::uniformMatrix2x4fv(GLint location,
4959 GLsizei count,
4960 GLboolean transpose,
4961 const GLfloat *value)
4962{
4963 Program *program = mGLState.getProgram();
4964 program->setUniformMatrix2x4fv(location, count, transpose, value);
4965}
4966
4967void Context::uniformMatrix4x2fv(GLint location,
4968 GLsizei count,
4969 GLboolean transpose,
4970 const GLfloat *value)
4971{
4972 Program *program = mGLState.getProgram();
4973 program->setUniformMatrix4x2fv(location, count, transpose, value);
4974}
4975
4976void Context::uniformMatrix3x4fv(GLint location,
4977 GLsizei count,
4978 GLboolean transpose,
4979 const GLfloat *value)
4980{
4981 Program *program = mGLState.getProgram();
4982 program->setUniformMatrix3x4fv(location, count, transpose, value);
4983}
4984
4985void Context::uniformMatrix4x3fv(GLint location,
4986 GLsizei count,
4987 GLboolean transpose,
4988 const GLfloat *value)
4989{
4990 Program *program = mGLState.getProgram();
4991 program->setUniformMatrix4x3fv(location, count, transpose, value);
4992}
4993
Jamie Madilld7576732017-08-26 18:49:50 -04004994void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
4995{
4996 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4997 {
4998 GLuint vertexArray = arrays[arrayIndex];
4999
5000 if (arrays[arrayIndex] != 0)
5001 {
5002 VertexArray *vertexArrayObject = nullptr;
5003 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
5004 {
5005 if (vertexArrayObject != nullptr)
5006 {
5007 detachVertexArray(vertexArray);
5008 vertexArrayObject->onDestroy(this);
5009 }
5010
5011 mVertexArrayHandleAllocator.release(vertexArray);
5012 }
5013 }
5014 }
5015}
5016
5017void Context::genVertexArrays(GLsizei n, GLuint *arrays)
5018{
5019 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
5020 {
5021 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
5022 mVertexArrayMap.assign(vertexArray, nullptr);
5023 arrays[arrayIndex] = vertexArray;
5024 }
5025}
5026
5027bool Context::isVertexArray(GLuint array)
5028{
5029 if (array == 0)
5030 {
5031 return GL_FALSE;
5032 }
5033
5034 VertexArray *vao = getVertexArray(array);
5035 return (vao != nullptr ? GL_TRUE : GL_FALSE);
5036}
5037
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04005038void Context::endTransformFeedback()
5039{
5040 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5041 transformFeedback->end(this);
5042}
5043
5044void Context::transformFeedbackVaryings(GLuint program,
5045 GLsizei count,
5046 const GLchar *const *varyings,
5047 GLenum bufferMode)
5048{
5049 Program *programObject = getProgram(program);
5050 ASSERT(programObject);
5051 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
5052}
5053
5054void Context::getTransformFeedbackVarying(GLuint program,
5055 GLuint index,
5056 GLsizei bufSize,
5057 GLsizei *length,
5058 GLsizei *size,
5059 GLenum *type,
5060 GLchar *name)
5061{
5062 Program *programObject = getProgram(program);
5063 ASSERT(programObject);
5064 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5065}
5066
5067void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5068{
5069 for (int i = 0; i < n; i++)
5070 {
5071 GLuint transformFeedback = ids[i];
5072 if (transformFeedback == 0)
5073 {
5074 continue;
5075 }
5076
5077 TransformFeedback *transformFeedbackObject = nullptr;
5078 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5079 {
5080 if (transformFeedbackObject != nullptr)
5081 {
5082 detachTransformFeedback(transformFeedback);
5083 transformFeedbackObject->release(this);
5084 }
5085
5086 mTransformFeedbackHandleAllocator.release(transformFeedback);
5087 }
5088 }
5089}
5090
5091void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5092{
5093 for (int i = 0; i < n; i++)
5094 {
5095 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5096 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5097 ids[i] = transformFeedback;
5098 }
5099}
5100
5101bool Context::isTransformFeedback(GLuint id)
5102{
5103 if (id == 0)
5104 {
5105 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5106 // returns FALSE
5107 return GL_FALSE;
5108 }
5109
5110 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5111 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5112}
5113
5114void Context::pauseTransformFeedback()
5115{
5116 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5117 transformFeedback->pause();
5118}
5119
5120void Context::resumeTransformFeedback()
5121{
5122 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5123 transformFeedback->resume();
5124}
5125
Jamie Madill12e957f2017-08-26 21:42:26 -04005126void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5127{
5128 const Program *programObject = getProgram(program);
Jamie Madill54164b02017-08-28 15:17:37 -04005129 programObject->getUniformuiv(this, location, params);
Jamie Madill12e957f2017-08-26 21:42:26 -04005130}
5131
5132GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5133{
5134 const Program *programObject = getProgram(program);
5135 return programObject->getFragDataLocation(name);
5136}
5137
5138void Context::getUniformIndices(GLuint program,
5139 GLsizei uniformCount,
5140 const GLchar *const *uniformNames,
5141 GLuint *uniformIndices)
5142{
5143 const Program *programObject = getProgram(program);
5144 if (!programObject->isLinked())
5145 {
5146 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5147 {
5148 uniformIndices[uniformId] = GL_INVALID_INDEX;
5149 }
5150 }
5151 else
5152 {
5153 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5154 {
5155 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5156 }
5157 }
5158}
5159
5160void Context::getActiveUniformsiv(GLuint program,
5161 GLsizei uniformCount,
5162 const GLuint *uniformIndices,
5163 GLenum pname,
5164 GLint *params)
5165{
5166 const Program *programObject = getProgram(program);
5167 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5168 {
5169 const GLuint index = uniformIndices[uniformId];
5170 params[uniformId] = programObject->getActiveUniformi(index, pname);
5171 }
5172}
5173
5174GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5175{
5176 const Program *programObject = getProgram(program);
5177 return programObject->getUniformBlockIndex(uniformBlockName);
5178}
5179
5180void Context::getActiveUniformBlockiv(GLuint program,
5181 GLuint uniformBlockIndex,
5182 GLenum pname,
5183 GLint *params)
5184{
5185 const Program *programObject = getProgram(program);
5186 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5187}
5188
5189void Context::getActiveUniformBlockName(GLuint program,
5190 GLuint uniformBlockIndex,
5191 GLsizei bufSize,
5192 GLsizei *length,
5193 GLchar *uniformBlockName)
5194{
5195 const Program *programObject = getProgram(program);
5196 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5197}
5198
5199void Context::uniformBlockBinding(GLuint program,
5200 GLuint uniformBlockIndex,
5201 GLuint uniformBlockBinding)
5202{
5203 Program *programObject = getProgram(program);
5204 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5205}
5206
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005207GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5208{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005209 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5210 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005211
Jamie Madill70b5bb02017-08-28 13:32:37 -04005212 Sync *syncObject = getSync(syncHandle);
5213 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005214 if (error.isError())
5215 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005216 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005217 handleError(error);
5218 return nullptr;
5219 }
5220
Jamie Madill70b5bb02017-08-28 13:32:37 -04005221 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005222}
5223
5224GLboolean Context::isSync(GLsync sync)
5225{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005226 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005227}
5228
5229GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5230{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005231 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005232
5233 GLenum result = GL_WAIT_FAILED;
5234 handleError(syncObject->clientWait(flags, timeout, &result));
5235 return result;
5236}
5237
5238void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5239{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005240 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005241 handleError(syncObject->serverWait(flags, timeout));
5242}
5243
5244void Context::getInteger64v(GLenum pname, GLint64 *params)
5245{
5246 GLenum nativeType = GL_NONE;
5247 unsigned int numParams = 0;
5248 getQueryParameterInfo(pname, &nativeType, &numParams);
5249
5250 if (nativeType == GL_INT_64_ANGLEX)
5251 {
5252 getInteger64vImpl(pname, params);
5253 }
5254 else
5255 {
5256 CastStateValues(this, nativeType, pname, numParams, params);
5257 }
5258}
5259
Jamie Madill3ef140a2017-08-26 23:11:21 -04005260void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5261{
5262 Buffer *buffer = mGLState.getTargetBuffer(target);
5263 QueryBufferParameteri64v(buffer, pname, params);
5264}
5265
5266void Context::genSamplers(GLsizei count, GLuint *samplers)
5267{
5268 for (int i = 0; i < count; i++)
5269 {
5270 samplers[i] = mState.mSamplers->createSampler();
5271 }
5272}
5273
5274void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5275{
5276 for (int i = 0; i < count; i++)
5277 {
5278 GLuint sampler = samplers[i];
5279
5280 if (mState.mSamplers->getSampler(sampler))
5281 {
5282 detachSampler(sampler);
5283 }
5284
5285 mState.mSamplers->deleteObject(this, sampler);
5286 }
5287}
5288
5289void Context::getInternalformativ(GLenum target,
5290 GLenum internalformat,
5291 GLenum pname,
5292 GLsizei bufSize,
5293 GLint *params)
5294{
5295 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5296 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5297}
5298
Jamie Madill81c2e252017-09-09 23:32:46 -04005299void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
5300{
5301 Program *programObject = getProgram(program);
5302 ASSERT(programObject);
5303 if (programObject->setUniform1iv(location, count, value) ==
5304 Program::SetUniformResult::SamplerChanged)
5305 {
5306 mGLState.setObjectDirty(GL_PROGRAM);
5307 }
5308}
5309
5310void Context::onTextureChange(const Texture *texture)
5311{
5312 // Conservatively assume all textures are dirty.
5313 // TODO(jmadill): More fine-grained update.
5314 mGLState.setObjectDirty(GL_TEXTURE);
5315}
5316
Yunchao Hea336b902017-08-02 16:05:21 +08005317void Context::genProgramPipelines(GLsizei count, GLuint *pipelines)
5318{
5319 for (int i = 0; i < count; i++)
5320 {
5321 pipelines[i] = createProgramPipeline();
5322 }
5323}
5324
5325void Context::deleteProgramPipelines(GLsizei count, const GLuint *pipelines)
5326{
5327 for (int i = 0; i < count; i++)
5328 {
5329 if (pipelines[i] != 0)
5330 {
5331 deleteProgramPipeline(pipelines[i]);
5332 }
5333 }
5334}
5335
5336GLboolean Context::isProgramPipeline(GLuint pipeline)
5337{
5338 if (pipeline == 0)
5339 {
5340 return GL_FALSE;
5341 }
5342
5343 return (getProgramPipeline(pipeline) ? GL_TRUE : GL_FALSE);
5344}
5345
Jamie Madillc29968b2016-01-20 11:17:23 -05005346} // namespace gl