blob: 94f3e121d6597720c9990f93de066587ccc54ee6 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madill231c7f52017-04-26 13:45:37 -040012#include <string.h>
Jamie Madillb9293972015-02-19 11:07:54 -050013#include <iterator>
14#include <sstream>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Jamie Madill948bbe52017-06-01 13:10:42 -040023#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Fence.h"
25#include "libANGLE/Framebuffer.h"
26#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070037#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040038#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030039#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040040#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040041#include "libANGLE/renderer/ContextImpl.h"
42#include "libANGLE/renderer/EGLImplFactory.h"
43#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Ian Ewell3ffd78b2016-01-22 16:09:42 -050048template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050049std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030050 GLsizei numPaths,
51 const void *paths,
52 GLuint pathBase)
53{
54 std::vector<gl::Path *> ret;
55 ret.reserve(numPaths);
56
57 const auto *nameArray = static_cast<const T *>(paths);
58
59 for (GLsizei i = 0; i < numPaths; ++i)
60 {
61 const GLuint pathName = nameArray[i] + pathBase;
62
63 ret.push_back(resourceManager.getPath(pathName));
64 }
65
66 return ret;
67}
68
Geoff Lang4ddf5af2016-12-01 14:30:44 -050069std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030070 GLsizei numPaths,
71 GLenum pathNameType,
72 const void *paths,
73 GLuint pathBase)
74{
75 switch (pathNameType)
76 {
77 case GL_UNSIGNED_BYTE:
78 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_BYTE:
81 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_UNSIGNED_SHORT:
84 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_SHORT:
87 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_INT:
90 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_INT:
93 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
94 }
95
96 UNREACHABLE();
97 return std::vector<gl::Path *>();
98}
99
100template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400101gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500102{
Geoff Lang2186c382016-10-14 10:54:54 -0400103 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500104
105 switch (pname)
106 {
107 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400108 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109 case GL_QUERY_RESULT_AVAILABLE_EXT:
110 {
111 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400112 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500113 if (!error.isError())
114 {
Geoff Lang2186c382016-10-14 10:54:54 -0400115 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500116 }
117 return error;
118 }
119 default:
120 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500121 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500122 }
123}
124
Geoff Langf6db0982015-08-25 13:04:00 -0400125void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
126{
Geoff Lang1a683462015-09-29 15:09:59 -0400127 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400128 {
129 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
130 tfBufferIndex++)
131 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400132 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400133 transformFeedback->getIndexedBuffer(tfBufferIndex);
134 if (buffer.get() != nullptr)
135 {
136 buffer->onTransformFeedback();
137 }
138 }
139 }
140}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141
142// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300143EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400145 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146}
147
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
149{
150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
151}
152
Geoff Langeb66a6e2016-10-31 13:06:12 -0400153gl::Version GetClientVersion(const egl::AttributeMap &attribs)
154{
155 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
156}
157
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500158GLenum GetResetStrategy(const egl::AttributeMap &attribs)
159{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400160 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
161 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500162 switch (attrib)
163 {
164 case EGL_NO_RESET_NOTIFICATION:
165 return GL_NO_RESET_NOTIFICATION_EXT;
166 case EGL_LOSE_CONTEXT_ON_RESET:
167 return GL_LOSE_CONTEXT_ON_RESET_EXT;
168 default:
169 UNREACHABLE();
170 return GL_NONE;
171 }
172}
173
174bool GetRobustAccess(const egl::AttributeMap &attribs)
175{
Geoff Lang077f20a2016-11-01 10:08:02 -0400176 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
177 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
178 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500179}
180
181bool GetDebug(const egl::AttributeMap &attribs)
182{
Geoff Lang077f20a2016-11-01 10:08:02 -0400183 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
184 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetNoError(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
190}
191
Geoff Langc287ea62016-09-16 14:46:51 -0400192bool GetWebGLContext(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langf41a7152016-09-19 15:11:17 -0400197bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
200}
201
Geoff Langfeb8c682017-02-13 16:07:35 -0500202bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
205}
206
Martin Radev9d901792016-07-15 15:58:58 +0300207std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
208{
209 std::string labelName;
210 if (label != nullptr)
211 {
212 size_t labelLength = length < 0 ? strlen(label) : length;
213 labelName = std::string(label, labelLength);
214 }
215 return labelName;
216}
217
218void GetObjectLabelBase(const std::string &objectLabel,
219 GLsizei bufSize,
220 GLsizei *length,
221 GLchar *label)
222{
223 size_t writeLength = objectLabel.length();
224 if (label != nullptr && bufSize > 0)
225 {
226 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
227 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
228 label[writeLength] = '\0';
229 }
230
231 if (length != nullptr)
232 {
233 *length = static_cast<GLsizei>(writeLength);
234 }
235}
236
Geoff Langf6db0982015-08-25 13:04:00 -0400237} // anonymous namespace
238
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000239namespace gl
240{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000241
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400242Context::Context(rx::EGLImplFactory *implFactory,
243 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400244 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500245 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500246 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400247 const egl::DisplayExtensions &displayExtensions,
248 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300249
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500250 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500251 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500252 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700253 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500254 mCaps,
255 mTextureCaps,
256 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500257 mLimitations,
258 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700259 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400260 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400261 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500262 mClientType(EGL_OPENGL_ES_API),
263 mHasBeenCurrent(false),
264 mContextLost(false),
265 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700266 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500267 mResetStrategy(GetResetStrategy(attribs)),
268 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400269 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
270 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500271 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500272 mWebGLContext(GetWebGLContext(attribs)),
273 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000274{
Geoff Lang077f20a2016-11-01 10:08:02 -0400275 if (mRobustAccess)
276 {
277 UNIMPLEMENTED();
278 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000279
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500280 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700281 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400282
Jamie Madill4928b7c2017-06-20 12:57:39 -0400283 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
284 GetClientArraysEnabled(attribs), robustResourceInit);
Régis Fénéon83107972015-02-05 12:57:44 +0100285
Shannon Woods53a94a82014-06-24 15:20:36 -0400286 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400287
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000288 // [OpenGL ES 2.0.24] section 3.7 page 83:
289 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
290 // and cube map texture state vectors respectively associated with them.
291 // In order that access to these initial textures not be lost, they are treated as texture
292 // objects all of whose names are 0.
293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400295 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400298 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400299
Geoff Langeb66a6e2016-10-31 13:06:12 -0400300 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400301 {
302 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400304 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400305
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400307 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308 }
Geoff Lang3b573612016-10-31 14:08:10 -0400309 if (getClientVersion() >= Version(3, 1))
310 {
311 Texture *zeroTexture2DMultisample =
312 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400313 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800314
315 bindGenericAtomicCounterBuffer(0);
316 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
317 {
318 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
319 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800320
321 bindGenericShaderStorageBuffer(0);
322 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
323 {
324 bindIndexedShaderStorageBuffer(0, i, 0, 0);
325 }
Geoff Lang3b573612016-10-31 14:08:10 -0400326 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000327
Ian Ewellbda75592016-04-18 17:25:54 -0400328 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
329 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400330 Texture *zeroTextureExternal =
331 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400332 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400333 }
334
Jamie Madill4928b7c2017-06-20 12:57:39 -0400335 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500336
Jamie Madill57a89722013-07-02 11:57:03 -0400337 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000338 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800339 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000340 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400341
Jamie Madill01a80ee2016-11-07 12:06:18 -0500342 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000343
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000344 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500345 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000346 {
347 bindIndexedUniformBuffer(0, i, 0, -1);
348 }
349
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000350 bindCopyReadBuffer(0);
351 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000352 bindPixelPackBuffer(0);
353 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000354
Geoff Langeb66a6e2016-10-31 13:06:12 -0400355 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400356 {
357 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
358 // In the initial state, a default transform feedback object is bound and treated as
359 // a transform feedback object with a name of zero. That object is bound any time
360 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400361 bindTransformFeedback(0);
362 }
Geoff Langc8058452014-02-03 12:04:11 -0500363
Jamie Madillad9f24e2016-02-12 09:27:24 -0500364 // Initialize dirty bit masks
365 // TODO(jmadill): additional ES3 state
366 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
367 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
368 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
369 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500373 // No dirty objects.
374
375 // Readpixels uses the pack state and read FBO
376 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
377 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
378 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
379 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500382 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
383
384 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
385 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
386 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
387 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
388 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
389 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
390 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
391 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
392 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
393 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
394 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
395 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
396
397 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
398 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700399 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500400 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
401 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400402
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400403 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000404}
405
Jamie Madill4928b7c2017-06-20 12:57:39 -0400406egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407{
Corentin Wallez80b24112015-08-25 16:41:57 -0400408 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000409 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000411 }
412
Corentin Wallez80b24112015-08-25 16:41:57 -0400413 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000414 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400415 if (query.second != nullptr)
416 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400417 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400418 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000419 }
420
Corentin Wallez80b24112015-08-25 16:41:57 -0400421 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400422 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400423 if (vertexArray.second)
424 {
425 vertexArray.second->onDestroy(this);
426 }
Jamie Madill57a89722013-07-02 11:57:03 -0400427 }
428
Corentin Wallez80b24112015-08-25 16:41:57 -0400429 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500430 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500431 if (transformFeedback.second != nullptr)
432 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500433 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500434 }
Geoff Langc8058452014-02-03 12:04:11 -0500435 }
436
Jamie Madilldedd7b92014-11-05 16:30:36 -0500437 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400438 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400439 zeroTexture.second->onDestroy(this);
440 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400441 }
442 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000443
Corentin Wallezccab69d2017-01-27 16:57:15 -0500444 SafeDelete(mSurfacelessFramebuffer);
445
Jamie Madill4928b7c2017-06-20 12:57:39 -0400446 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400447 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500448
Jamie Madill4928b7c2017-06-20 12:57:39 -0400449 mGLState.reset(this);
450
Jamie Madill6c1f6712017-02-14 19:08:04 -0500451 mState.mBuffers->release(this);
452 mState.mShaderPrograms->release(this);
453 mState.mTextures->release(this);
454 mState.mRenderbuffers->release(this);
455 mState.mSamplers->release(this);
456 mState.mFenceSyncs->release(this);
457 mState.mPaths->release(this);
458 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400459
460 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000461}
462
Jamie Madill70ee0f62017-02-06 16:04:20 -0500463Context::~Context()
464{
465}
466
Jamie Madill4928b7c2017-06-20 12:57:39 -0400467egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000468{
Jamie Madill61e16b42017-06-19 11:13:23 -0400469 mCurrentDisplay = display;
470
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000471 if (!mHasBeenCurrent)
472 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000473 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500474 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400475 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000476
Corentin Wallezc295e512017-01-27 17:47:50 -0500477 int width = 0;
478 int height = 0;
479 if (surface != nullptr)
480 {
481 width = surface->getWidth();
482 height = surface->getHeight();
483 }
484
485 mGLState.setViewportParams(0, 0, width, height);
486 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000487
488 mHasBeenCurrent = true;
489 }
490
Jamie Madill1b94d432015-08-07 13:23:23 -0400491 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700492 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400493
Jamie Madill4928b7c2017-06-20 12:57:39 -0400494 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500495
496 Framebuffer *newDefault = nullptr;
497 if (surface != nullptr)
498 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400499 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500500 mCurrentSurface = surface;
501 newDefault = surface->getDefaultFramebuffer();
502 }
503 else
504 {
505 if (mSurfacelessFramebuffer == nullptr)
506 {
507 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
508 }
509
510 newDefault = mSurfacelessFramebuffer;
511 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000512
Corentin Wallez37c39792015-08-20 14:19:46 -0400513 // Update default framebuffer, the binding of the previous default
514 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400515 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700516 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400517 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700518 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400519 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700520 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400521 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700522 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400523 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500524 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400525 }
Ian Ewell292f0052016-02-04 10:37:32 -0500526
527 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400528 mImplementation->onMakeCurrent(this);
529 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000530}
531
Jamie Madill4928b7c2017-06-20 12:57:39 -0400532egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400533{
Corentin Wallez37c39792015-08-20 14:19:46 -0400534 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500535 Framebuffer *currentDefault = nullptr;
536 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400537 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500538 currentDefault = mCurrentSurface->getDefaultFramebuffer();
539 }
540 else if (mSurfacelessFramebuffer != nullptr)
541 {
542 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400543 }
544
Corentin Wallezc295e512017-01-27 17:47:50 -0500545 if (mGLState.getReadFramebuffer() == currentDefault)
546 {
547 mGLState.setReadFramebufferBinding(nullptr);
548 }
549 if (mGLState.getDrawFramebuffer() == currentDefault)
550 {
551 mGLState.setDrawFramebufferBinding(nullptr);
552 }
553 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
554
555 if (mCurrentSurface)
556 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400557 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500558 mCurrentSurface = nullptr;
559 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400560
561 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400562}
563
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000564GLuint Context::createBuffer()
565{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500566 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000567}
568
569GLuint Context::createProgram()
570{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500571 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000572}
573
574GLuint Context::createShader(GLenum type)
575{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500576 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000577}
578
579GLuint Context::createTexture()
580{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500581 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000582}
583
584GLuint Context::createRenderbuffer()
585{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500586 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587}
588
Geoff Lang882033e2014-09-30 11:26:07 -0400589GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400590{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500591 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400592
Cooper Partind8e62a32015-01-29 15:21:25 -0800593 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400594}
595
Sami Väisänene45e53b2016-05-25 10:36:04 +0300596GLuint Context::createPaths(GLsizei range)
597{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500598 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300599 if (resultOrError.isError())
600 {
601 handleError(resultOrError.getError());
602 return 0;
603 }
604 return resultOrError.getResult();
605}
606
Jamie Madill57a89722013-07-02 11:57:03 -0400607GLuint Context::createVertexArray()
608{
Geoff Lang36167ab2015-12-07 10:27:14 -0500609 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
610 mVertexArrayMap[vertexArray] = nullptr;
611 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400612}
613
Jamie Madilldc356042013-07-19 16:36:57 -0400614GLuint Context::createSampler()
615{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500616 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400617}
618
Geoff Langc8058452014-02-03 12:04:11 -0500619GLuint Context::createTransformFeedback()
620{
Geoff Lang36167ab2015-12-07 10:27:14 -0500621 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
622 mTransformFeedbackMap[transformFeedback] = nullptr;
623 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500624}
625
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626// Returns an unused framebuffer name
627GLuint Context::createFramebuffer()
628{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500629 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630}
631
Jamie Madill33dc8432013-07-26 11:55:05 -0400632GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633{
Jamie Madill33dc8432013-07-26 11:55:05 -0400634 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000635
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400636 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637
638 return handle;
639}
640
641// Returns an unused query name
642GLuint Context::createQuery()
643{
644 GLuint handle = mQueryHandleAllocator.allocate();
645
Yunchao Hed7297bf2017-04-19 15:27:10 +0800646 mQueryMap[handle] = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000647
648 return handle;
649}
650
651void Context::deleteBuffer(GLuint buffer)
652{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500653 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000654 {
655 detachBuffer(buffer);
656 }
Jamie Madill893ab082014-05-16 16:56:10 -0400657
Jamie Madill6c1f6712017-02-14 19:08:04 -0500658 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659}
660
661void Context::deleteShader(GLuint shader)
662{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500663 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000664}
665
666void Context::deleteProgram(GLuint program)
667{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500668 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000669}
670
671void Context::deleteTexture(GLuint texture)
672{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500673 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000674 {
675 detachTexture(texture);
676 }
677
Jamie Madill6c1f6712017-02-14 19:08:04 -0500678 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000679}
680
681void Context::deleteRenderbuffer(GLuint renderbuffer)
682{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500683 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000684 {
685 detachRenderbuffer(renderbuffer);
686 }
Jamie Madill893ab082014-05-16 16:56:10 -0400687
Jamie Madill6c1f6712017-02-14 19:08:04 -0500688 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000689}
690
Jamie Madillcd055f82013-07-26 11:55:15 -0400691void Context::deleteFenceSync(GLsync fenceSync)
692{
693 // The spec specifies the underlying Fence object is not deleted until all current
694 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
695 // and since our API is currently designed for being called from a single thread, we can delete
696 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500697 mState.mFenceSyncs->deleteObject(this,
698 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400699}
700
Sami Väisänene45e53b2016-05-25 10:36:04 +0300701void Context::deletePaths(GLuint first, GLsizei range)
702{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500703 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300704}
705
706bool Context::hasPathData(GLuint path) const
707{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500708 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300709 if (pathObj == nullptr)
710 return false;
711
712 return pathObj->hasPathData();
713}
714
715bool Context::hasPath(GLuint path) const
716{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500717 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300718}
719
720void Context::setPathCommands(GLuint path,
721 GLsizei numCommands,
722 const GLubyte *commands,
723 GLsizei numCoords,
724 GLenum coordType,
725 const void *coords)
726{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500727 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300728
729 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
730}
731
732void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
733{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500734 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300735
736 switch (pname)
737 {
738 case GL_PATH_STROKE_WIDTH_CHROMIUM:
739 pathObj->setStrokeWidth(value);
740 break;
741 case GL_PATH_END_CAPS_CHROMIUM:
742 pathObj->setEndCaps(static_cast<GLenum>(value));
743 break;
744 case GL_PATH_JOIN_STYLE_CHROMIUM:
745 pathObj->setJoinStyle(static_cast<GLenum>(value));
746 break;
747 case GL_PATH_MITER_LIMIT_CHROMIUM:
748 pathObj->setMiterLimit(value);
749 break;
750 case GL_PATH_STROKE_BOUND_CHROMIUM:
751 pathObj->setStrokeBound(value);
752 break;
753 default:
754 UNREACHABLE();
755 break;
756 }
757}
758
759void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
760{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500761 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300762
763 switch (pname)
764 {
765 case GL_PATH_STROKE_WIDTH_CHROMIUM:
766 *value = pathObj->getStrokeWidth();
767 break;
768 case GL_PATH_END_CAPS_CHROMIUM:
769 *value = static_cast<GLfloat>(pathObj->getEndCaps());
770 break;
771 case GL_PATH_JOIN_STYLE_CHROMIUM:
772 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
773 break;
774 case GL_PATH_MITER_LIMIT_CHROMIUM:
775 *value = pathObj->getMiterLimit();
776 break;
777 case GL_PATH_STROKE_BOUND_CHROMIUM:
778 *value = pathObj->getStrokeBound();
779 break;
780 default:
781 UNREACHABLE();
782 break;
783 }
784}
785
786void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
787{
788 mGLState.setPathStencilFunc(func, ref, mask);
789}
790
Jamie Madill57a89722013-07-02 11:57:03 -0400791void Context::deleteVertexArray(GLuint vertexArray)
792{
Geoff Lang36167ab2015-12-07 10:27:14 -0500793 auto iter = mVertexArrayMap.find(vertexArray);
794 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000795 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500796 VertexArray *vertexArrayObject = iter->second;
797 if (vertexArrayObject != nullptr)
798 {
799 detachVertexArray(vertexArray);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400800 vertexArrayObject->onDestroy(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500801 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000802
Geoff Lang36167ab2015-12-07 10:27:14 -0500803 mVertexArrayMap.erase(iter);
804 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400805 }
806}
807
Jamie Madilldc356042013-07-19 16:36:57 -0400808void Context::deleteSampler(GLuint sampler)
809{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500810 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400811 {
812 detachSampler(sampler);
813 }
814
Jamie Madill6c1f6712017-02-14 19:08:04 -0500815 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400816}
817
Geoff Langc8058452014-02-03 12:04:11 -0500818void Context::deleteTransformFeedback(GLuint transformFeedback)
819{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400820 if (transformFeedback == 0)
821 {
822 return;
823 }
824
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500825 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500826 if (iter != mTransformFeedbackMap.end())
827 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500828 TransformFeedback *transformFeedbackObject = iter->second;
829 if (transformFeedbackObject != nullptr)
830 {
831 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500832 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500833 }
834
Geoff Lang50b3fe82015-12-08 14:49:12 +0000835 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500836 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500837 }
838}
839
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840void Context::deleteFramebuffer(GLuint framebuffer)
841{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500842 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843 {
844 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000845 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500846
Jamie Madill6c1f6712017-02-14 19:08:04 -0500847 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000848}
849
Jamie Madill33dc8432013-07-26 11:55:05 -0400850void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000851{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500852 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000853
Jamie Madill33dc8432013-07-26 11:55:05 -0400854 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400856 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000857 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400858 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000859 }
860}
861
862void Context::deleteQuery(GLuint query)
863{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500864 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000865 if (queryObject != mQueryMap.end())
866 {
867 mQueryHandleAllocator.release(queryObject->first);
868 if (queryObject->second)
869 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400870 queryObject->second->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000871 }
872 mQueryMap.erase(queryObject);
873 }
874}
875
Geoff Lang70d0f492015-12-10 17:45:46 -0500876Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000877{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500878 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000879}
880
Jamie Madill570f7c82014-07-03 10:38:54 -0400881Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000882{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500883 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000884}
885
Geoff Lang70d0f492015-12-10 17:45:46 -0500886Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000887{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500888 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000889}
890
Jamie Madillcd055f82013-07-26 11:55:15 -0400891FenceSync *Context::getFenceSync(GLsync handle) const
892{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500893 return mState.mFenceSyncs->getFenceSync(
894 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400895}
896
Jamie Madill57a89722013-07-02 11:57:03 -0400897VertexArray *Context::getVertexArray(GLuint handle) const
898{
899 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500900 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400901}
902
Jamie Madilldc356042013-07-19 16:36:57 -0400903Sampler *Context::getSampler(GLuint handle) const
904{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500905 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400906}
907
Geoff Langc8058452014-02-03 12:04:11 -0500908TransformFeedback *Context::getTransformFeedback(GLuint handle) const
909{
Geoff Lang36167ab2015-12-07 10:27:14 -0500910 auto iter = mTransformFeedbackMap.find(handle);
911 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500912}
913
Geoff Lang70d0f492015-12-10 17:45:46 -0500914LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
915{
916 switch (identifier)
917 {
918 case GL_BUFFER:
919 return getBuffer(name);
920 case GL_SHADER:
921 return getShader(name);
922 case GL_PROGRAM:
923 return getProgram(name);
924 case GL_VERTEX_ARRAY:
925 return getVertexArray(name);
926 case GL_QUERY:
927 return getQuery(name);
928 case GL_TRANSFORM_FEEDBACK:
929 return getTransformFeedback(name);
930 case GL_SAMPLER:
931 return getSampler(name);
932 case GL_TEXTURE:
933 return getTexture(name);
934 case GL_RENDERBUFFER:
935 return getRenderbuffer(name);
936 case GL_FRAMEBUFFER:
937 return getFramebuffer(name);
938 default:
939 UNREACHABLE();
940 return nullptr;
941 }
942}
943
944LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
945{
946 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
947}
948
Martin Radev9d901792016-07-15 15:58:58 +0300949void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
950{
951 LabeledObject *object = getLabeledObject(identifier, name);
952 ASSERT(object != nullptr);
953
954 std::string labelName = GetObjectLabelFromPointer(length, label);
955 object->setLabel(labelName);
956}
957
958void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
959{
960 LabeledObject *object = getLabeledObjectFromPtr(ptr);
961 ASSERT(object != nullptr);
962
963 std::string labelName = GetObjectLabelFromPointer(length, label);
964 object->setLabel(labelName);
965}
966
967void Context::getObjectLabel(GLenum identifier,
968 GLuint name,
969 GLsizei bufSize,
970 GLsizei *length,
971 GLchar *label) const
972{
973 LabeledObject *object = getLabeledObject(identifier, name);
974 ASSERT(object != nullptr);
975
976 const std::string &objectLabel = object->getLabel();
977 GetObjectLabelBase(objectLabel, bufSize, length, label);
978}
979
980void Context::getObjectPtrLabel(const void *ptr,
981 GLsizei bufSize,
982 GLsizei *length,
983 GLchar *label) const
984{
985 LabeledObject *object = getLabeledObjectFromPtr(ptr);
986 ASSERT(object != nullptr);
987
988 const std::string &objectLabel = object->getLabel();
989 GetObjectLabelBase(objectLabel, bufSize, length, label);
990}
991
Jamie Madilldc356042013-07-19 16:36:57 -0400992bool Context::isSampler(GLuint samplerName) const
993{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500994 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400995}
996
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500997void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000998{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500999 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001000 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001001}
1002
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001003void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
1004{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001005 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001006 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001007}
1008
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001009void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001010{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001011 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001012 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001013}
1014
Jamie Madilldedd7b92014-11-05 16:30:36 -05001015void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001016{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001017 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001018
Jamie Madilldedd7b92014-11-05 16:30:36 -05001019 if (handle == 0)
1020 {
1021 texture = mZeroTextures[target].get();
1022 }
1023 else
1024 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001025 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001026 }
1027
1028 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001029 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001030}
1031
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001032void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001033{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001034 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1035 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001036 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001037}
1038
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001039void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001040{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001041 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1042 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001043 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001044}
1045
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001046void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001047{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001048 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001049 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001050}
1051
Shao80957d92017-02-20 21:25:59 +08001052void Context::bindVertexBuffer(GLuint bindingIndex,
1053 GLuint bufferHandle,
1054 GLintptr offset,
1055 GLsizei stride)
1056{
1057 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001058 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001059}
1060
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001061void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001062{
Geoff Lang76b10c92014-09-05 16:28:14 -04001063 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001064 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001065 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001066 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001067}
1068
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001069void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001070{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001071 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001072 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001073}
1074
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001075void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1076 GLuint index,
1077 GLintptr offset,
1078 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +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.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001082}
1083
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001084void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +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.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001088}
1089
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001090void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1091 GLuint index,
1092 GLintptr offset,
1093 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001094{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001095 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001096 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001097}
1098
Jiajia Qin6eafb042016-12-27 17:04:07 +08001099void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1100{
1101 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001102 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001103}
1104
1105void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1106 GLuint index,
1107 GLintptr offset,
1108 GLsizeiptr size)
1109{
1110 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001111 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001112}
1113
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001114void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1115{
1116 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001117 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001118}
1119
1120void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1121 GLuint index,
1122 GLintptr offset,
1123 GLsizeiptr size)
1124{
1125 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001126 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001127}
1128
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001129void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001130{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001131 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001132 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001133}
1134
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001135void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001136{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001137 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001138 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001139}
1140
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001141void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001142{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001143 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001144 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001145}
1146
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001147void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001148{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001149 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001150 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001151}
1152
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001153void Context::useProgram(GLuint program)
1154{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001155 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001156}
1157
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001158void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001159{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001160 TransformFeedback *transformFeedback =
1161 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001162 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001163}
1164
Geoff Lang5aad9672014-09-08 11:10:42 -04001165Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001166{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001168 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001169
Geoff Lang5aad9672014-09-08 11:10:42 -04001170 // begin query
1171 Error error = queryObject->begin();
1172 if (error.isError())
1173 {
1174 return error;
1175 }
1176
1177 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001178 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179
He Yunchaoacd18982017-01-04 10:46:42 +08001180 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181}
1182
Geoff Lang5aad9672014-09-08 11:10:42 -04001183Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001185 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001186 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187
Geoff Lang5aad9672014-09-08 11:10:42 -04001188 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189
Geoff Lang5aad9672014-09-08 11:10:42 -04001190 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001191 mGLState.setActiveQuery(this, target, nullptr);
Geoff Lang5aad9672014-09-08 11:10:42 -04001192
1193 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001194}
1195
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001196Error Context::queryCounter(GLuint id, GLenum target)
1197{
1198 ASSERT(target == GL_TIMESTAMP_EXT);
1199
1200 Query *queryObject = getQuery(id, true, target);
1201 ASSERT(queryObject);
1202
1203 return queryObject->queryCounter();
1204}
1205
1206void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1207{
1208 switch (pname)
1209 {
1210 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001211 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001212 break;
1213 case GL_QUERY_COUNTER_BITS_EXT:
1214 switch (target)
1215 {
1216 case GL_TIME_ELAPSED_EXT:
1217 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1218 break;
1219 case GL_TIMESTAMP_EXT:
1220 params[0] = getExtensions().queryCounterBitsTimestamp;
1221 break;
1222 default:
1223 UNREACHABLE();
1224 params[0] = 0;
1225 break;
1226 }
1227 break;
1228 default:
1229 UNREACHABLE();
1230 return;
1231 }
1232}
1233
Geoff Lang2186c382016-10-14 10:54:54 -04001234void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001235{
Geoff Lang2186c382016-10-14 10:54:54 -04001236 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001237}
1238
Geoff Lang2186c382016-10-14 10:54:54 -04001239void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001240{
Geoff Lang2186c382016-10-14 10:54:54 -04001241 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001242}
1243
Geoff Lang2186c382016-10-14 10:54:54 -04001244void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001245{
Geoff Lang2186c382016-10-14 10:54:54 -04001246 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001247}
1248
Geoff Lang2186c382016-10-14 10:54:54 -04001249void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001250{
Geoff Lang2186c382016-10-14 10:54:54 -04001251 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001252}
1253
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001254Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001256 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001257}
1258
Jamie Madill2f348d22017-06-05 10:50:59 -04001259FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001260{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001261 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262
Jamie Madill33dc8432013-07-26 11:55:05 -04001263 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001264 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001265 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266 }
1267 else
1268 {
1269 return fence->second;
1270 }
1271}
1272
Jamie Madill2f348d22017-06-05 10:50:59 -04001273Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001275 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276
1277 if (query == mQueryMap.end())
1278 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001279 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280 }
1281 else
1282 {
1283 if (!query->second && create)
1284 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001285 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001286 query->second->addRef();
1287 }
1288 return query->second;
1289 }
1290}
1291
Geoff Lang70d0f492015-12-10 17:45:46 -05001292Query *Context::getQuery(GLuint handle) const
1293{
1294 auto iter = mQueryMap.find(handle);
1295 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1296}
1297
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001298Texture *Context::getTargetTexture(GLenum target) const
1299{
Ian Ewellbda75592016-04-18 17:25:54 -04001300 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001301 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001302}
1303
Geoff Lang76b10c92014-09-05 16:28:14 -04001304Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001305{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001306 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001307}
1308
Geoff Lang492a7e42014-11-05 13:27:06 -05001309Compiler *Context::getCompiler() const
1310{
Jamie Madill2f348d22017-06-05 10:50:59 -04001311 if (mCompiler.get() == nullptr)
1312 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001313 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001314 }
1315 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001316}
1317
Jamie Madillc1d770e2017-04-13 17:31:24 -04001318void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001319{
1320 switch (pname)
1321 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001322 case GL_SHADER_COMPILER:
1323 *params = GL_TRUE;
1324 break;
1325 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1326 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1327 break;
1328 default:
1329 mGLState.getBooleanv(pname, params);
1330 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001331 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332}
1333
Jamie Madillc1d770e2017-04-13 17:31:24 -04001334void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001335{
Shannon Woods53a94a82014-06-24 15:20:36 -04001336 // Queries about context capabilities and maximums are answered by Context.
1337 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001338 switch (pname)
1339 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001340 case GL_ALIASED_LINE_WIDTH_RANGE:
1341 params[0] = mCaps.minAliasedLineWidth;
1342 params[1] = mCaps.maxAliasedLineWidth;
1343 break;
1344 case GL_ALIASED_POINT_SIZE_RANGE:
1345 params[0] = mCaps.minAliasedPointSize;
1346 params[1] = mCaps.maxAliasedPointSize;
1347 break;
1348 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1349 ASSERT(mExtensions.textureFilterAnisotropic);
1350 *params = mExtensions.maxTextureAnisotropy;
1351 break;
1352 case GL_MAX_TEXTURE_LOD_BIAS:
1353 *params = mCaps.maxLODBias;
1354 break;
1355
1356 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1357 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1358 {
1359 ASSERT(mExtensions.pathRendering);
1360 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1361 memcpy(params, m, 16 * sizeof(GLfloat));
1362 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001363 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001364
Jamie Madill231c7f52017-04-26 13:45:37 -04001365 default:
1366 mGLState.getFloatv(pname, params);
1367 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001368 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001369}
1370
Jamie Madillc1d770e2017-04-13 17:31:24 -04001371void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001372{
Shannon Woods53a94a82014-06-24 15:20:36 -04001373 // Queries about context capabilities and maximums are answered by Context.
1374 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001375
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001376 switch (pname)
1377 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001378 case GL_MAX_VERTEX_ATTRIBS:
1379 *params = mCaps.maxVertexAttributes;
1380 break;
1381 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1382 *params = mCaps.maxVertexUniformVectors;
1383 break;
1384 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1385 *params = mCaps.maxVertexUniformComponents;
1386 break;
1387 case GL_MAX_VARYING_VECTORS:
1388 *params = mCaps.maxVaryingVectors;
1389 break;
1390 case GL_MAX_VARYING_COMPONENTS:
1391 *params = mCaps.maxVertexOutputComponents;
1392 break;
1393 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1394 *params = mCaps.maxCombinedTextureImageUnits;
1395 break;
1396 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1397 *params = mCaps.maxVertexTextureImageUnits;
1398 break;
1399 case GL_MAX_TEXTURE_IMAGE_UNITS:
1400 *params = mCaps.maxTextureImageUnits;
1401 break;
1402 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1403 *params = mCaps.maxFragmentUniformVectors;
1404 break;
1405 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1406 *params = mCaps.maxFragmentUniformComponents;
1407 break;
1408 case GL_MAX_RENDERBUFFER_SIZE:
1409 *params = mCaps.maxRenderbufferSize;
1410 break;
1411 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1412 *params = mCaps.maxColorAttachments;
1413 break;
1414 case GL_MAX_DRAW_BUFFERS_EXT:
1415 *params = mCaps.maxDrawBuffers;
1416 break;
1417 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1418 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1419 case GL_SUBPIXEL_BITS:
1420 *params = 4;
1421 break;
1422 case GL_MAX_TEXTURE_SIZE:
1423 *params = mCaps.max2DTextureSize;
1424 break;
1425 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1426 *params = mCaps.maxCubeMapTextureSize;
1427 break;
1428 case GL_MAX_3D_TEXTURE_SIZE:
1429 *params = mCaps.max3DTextureSize;
1430 break;
1431 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1432 *params = mCaps.maxArrayTextureLayers;
1433 break;
1434 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1435 *params = mCaps.uniformBufferOffsetAlignment;
1436 break;
1437 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1438 *params = mCaps.maxUniformBufferBindings;
1439 break;
1440 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1441 *params = mCaps.maxVertexUniformBlocks;
1442 break;
1443 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1444 *params = mCaps.maxFragmentUniformBlocks;
1445 break;
1446 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1447 *params = mCaps.maxCombinedTextureImageUnits;
1448 break;
1449 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1450 *params = mCaps.maxVertexOutputComponents;
1451 break;
1452 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1453 *params = mCaps.maxFragmentInputComponents;
1454 break;
1455 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1456 *params = mCaps.minProgramTexelOffset;
1457 break;
1458 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1459 *params = mCaps.maxProgramTexelOffset;
1460 break;
1461 case GL_MAJOR_VERSION:
1462 *params = getClientVersion().major;
1463 break;
1464 case GL_MINOR_VERSION:
1465 *params = getClientVersion().minor;
1466 break;
1467 case GL_MAX_ELEMENTS_INDICES:
1468 *params = mCaps.maxElementsIndices;
1469 break;
1470 case GL_MAX_ELEMENTS_VERTICES:
1471 *params = mCaps.maxElementsVertices;
1472 break;
1473 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1474 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1475 break;
1476 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1477 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1478 break;
1479 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1480 *params = mCaps.maxTransformFeedbackSeparateComponents;
1481 break;
1482 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1483 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1484 break;
1485 case GL_MAX_SAMPLES_ANGLE:
1486 *params = mCaps.maxSamples;
1487 break;
1488 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001489 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001490 params[0] = mCaps.maxViewportWidth;
1491 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001492 }
1493 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001494 case GL_COMPRESSED_TEXTURE_FORMATS:
1495 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1496 params);
1497 break;
1498 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1499 *params = mResetStrategy;
1500 break;
1501 case GL_NUM_SHADER_BINARY_FORMATS:
1502 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1503 break;
1504 case GL_SHADER_BINARY_FORMATS:
1505 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1506 break;
1507 case GL_NUM_PROGRAM_BINARY_FORMATS:
1508 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1509 break;
1510 case GL_PROGRAM_BINARY_FORMATS:
1511 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1512 break;
1513 case GL_NUM_EXTENSIONS:
1514 *params = static_cast<GLint>(mExtensionStrings.size());
1515 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001516
Jamie Madill231c7f52017-04-26 13:45:37 -04001517 // GL_KHR_debug
1518 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1519 *params = mExtensions.maxDebugMessageLength;
1520 break;
1521 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1522 *params = mExtensions.maxDebugLoggedMessages;
1523 break;
1524 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1525 *params = mExtensions.maxDebugGroupStackDepth;
1526 break;
1527 case GL_MAX_LABEL_LENGTH:
1528 *params = mExtensions.maxLabelLength;
1529 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001530
Jamie Madill231c7f52017-04-26 13:45:37 -04001531 // GL_EXT_disjoint_timer_query
1532 case GL_GPU_DISJOINT_EXT:
1533 *params = mImplementation->getGPUDisjoint();
1534 break;
1535 case GL_MAX_FRAMEBUFFER_WIDTH:
1536 *params = mCaps.maxFramebufferWidth;
1537 break;
1538 case GL_MAX_FRAMEBUFFER_HEIGHT:
1539 *params = mCaps.maxFramebufferHeight;
1540 break;
1541 case GL_MAX_FRAMEBUFFER_SAMPLES:
1542 *params = mCaps.maxFramebufferSamples;
1543 break;
1544 case GL_MAX_SAMPLE_MASK_WORDS:
1545 *params = mCaps.maxSampleMaskWords;
1546 break;
1547 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1548 *params = mCaps.maxColorTextureSamples;
1549 break;
1550 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1551 *params = mCaps.maxDepthTextureSamples;
1552 break;
1553 case GL_MAX_INTEGER_SAMPLES:
1554 *params = mCaps.maxIntegerSamples;
1555 break;
1556 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1557 *params = mCaps.maxVertexAttribRelativeOffset;
1558 break;
1559 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1560 *params = mCaps.maxVertexAttribBindings;
1561 break;
1562 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1563 *params = mCaps.maxVertexAttribStride;
1564 break;
1565 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1566 *params = mCaps.maxVertexAtomicCounterBuffers;
1567 break;
1568 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1569 *params = mCaps.maxVertexAtomicCounters;
1570 break;
1571 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1572 *params = mCaps.maxVertexImageUniforms;
1573 break;
1574 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1575 *params = mCaps.maxVertexShaderStorageBlocks;
1576 break;
1577 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1578 *params = mCaps.maxFragmentAtomicCounterBuffers;
1579 break;
1580 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1581 *params = mCaps.maxFragmentAtomicCounters;
1582 break;
1583 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1584 *params = mCaps.maxFragmentImageUniforms;
1585 break;
1586 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1587 *params = mCaps.maxFragmentShaderStorageBlocks;
1588 break;
1589 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1590 *params = mCaps.minProgramTextureGatherOffset;
1591 break;
1592 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1593 *params = mCaps.maxProgramTextureGatherOffset;
1594 break;
1595 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1596 *params = mCaps.maxComputeWorkGroupInvocations;
1597 break;
1598 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1599 *params = mCaps.maxComputeUniformBlocks;
1600 break;
1601 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1602 *params = mCaps.maxComputeTextureImageUnits;
1603 break;
1604 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1605 *params = mCaps.maxComputeSharedMemorySize;
1606 break;
1607 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1608 *params = mCaps.maxComputeUniformComponents;
1609 break;
1610 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1611 *params = mCaps.maxComputeAtomicCounterBuffers;
1612 break;
1613 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1614 *params = mCaps.maxComputeAtomicCounters;
1615 break;
1616 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1617 *params = mCaps.maxComputeImageUniforms;
1618 break;
1619 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1620 *params = mCaps.maxCombinedComputeUniformComponents;
1621 break;
1622 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1623 *params = mCaps.maxComputeShaderStorageBlocks;
1624 break;
1625 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1626 *params = mCaps.maxCombinedShaderOutputResources;
1627 break;
1628 case GL_MAX_UNIFORM_LOCATIONS:
1629 *params = mCaps.maxUniformLocations;
1630 break;
1631 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1632 *params = mCaps.maxAtomicCounterBufferBindings;
1633 break;
1634 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1635 *params = mCaps.maxAtomicCounterBufferSize;
1636 break;
1637 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1638 *params = mCaps.maxCombinedAtomicCounterBuffers;
1639 break;
1640 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1641 *params = mCaps.maxCombinedAtomicCounters;
1642 break;
1643 case GL_MAX_IMAGE_UNITS:
1644 *params = mCaps.maxImageUnits;
1645 break;
1646 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1647 *params = mCaps.maxCombinedImageUniforms;
1648 break;
1649 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1650 *params = mCaps.maxShaderStorageBufferBindings;
1651 break;
1652 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1653 *params = mCaps.maxCombinedShaderStorageBlocks;
1654 break;
1655 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1656 *params = mCaps.shaderStorageBufferOffsetAlignment;
1657 break;
1658 default:
1659 mGLState.getIntegerv(this, pname, params);
1660 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001661 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001662}
1663
Jamie Madill893ab082014-05-16 16:56:10 -04001664void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001665{
Shannon Woods53a94a82014-06-24 15:20:36 -04001666 // Queries about context capabilities and maximums are answered by Context.
1667 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001668 switch (pname)
1669 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001670 case GL_MAX_ELEMENT_INDEX:
1671 *params = mCaps.maxElementIndex;
1672 break;
1673 case GL_MAX_UNIFORM_BLOCK_SIZE:
1674 *params = mCaps.maxUniformBlockSize;
1675 break;
1676 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1677 *params = mCaps.maxCombinedVertexUniformComponents;
1678 break;
1679 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1680 *params = mCaps.maxCombinedFragmentUniformComponents;
1681 break;
1682 case GL_MAX_SERVER_WAIT_TIMEOUT:
1683 *params = mCaps.maxServerWaitTimeout;
1684 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001685
Jamie Madill231c7f52017-04-26 13:45:37 -04001686 // GL_EXT_disjoint_timer_query
1687 case GL_TIMESTAMP_EXT:
1688 *params = mImplementation->getTimestamp();
1689 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001690
Jamie Madill231c7f52017-04-26 13:45:37 -04001691 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1692 *params = mCaps.maxShaderStorageBlockSize;
1693 break;
1694 default:
1695 UNREACHABLE();
1696 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001697 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001698}
1699
Geoff Lang70d0f492015-12-10 17:45:46 -05001700void Context::getPointerv(GLenum pname, void **params) const
1701{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001702 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001703}
1704
Martin Radev66fb8202016-07-28 11:45:20 +03001705void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001706{
Shannon Woods53a94a82014-06-24 15:20:36 -04001707 // Queries about context capabilities and maximums are answered by Context.
1708 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001709
1710 GLenum nativeType;
1711 unsigned int numParams;
1712 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1713 ASSERT(queryStatus);
1714
1715 if (nativeType == GL_INT)
1716 {
1717 switch (target)
1718 {
1719 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1720 ASSERT(index < 3u);
1721 *data = mCaps.maxComputeWorkGroupCount[index];
1722 break;
1723 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1724 ASSERT(index < 3u);
1725 *data = mCaps.maxComputeWorkGroupSize[index];
1726 break;
1727 default:
1728 mGLState.getIntegeri_v(target, index, data);
1729 }
1730 }
1731 else
1732 {
1733 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1734 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001735}
1736
Martin Radev66fb8202016-07-28 11:45:20 +03001737void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001738{
Shannon Woods53a94a82014-06-24 15:20:36 -04001739 // Queries about context capabilities and maximums are answered by Context.
1740 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001741
1742 GLenum nativeType;
1743 unsigned int numParams;
1744 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1745 ASSERT(queryStatus);
1746
1747 if (nativeType == GL_INT_64_ANGLEX)
1748 {
1749 mGLState.getInteger64i_v(target, index, data);
1750 }
1751 else
1752 {
1753 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1754 }
1755}
1756
1757void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1758{
1759 // Queries about context capabilities and maximums are answered by Context.
1760 // Queries about current GL state values are answered by State.
1761
1762 GLenum nativeType;
1763 unsigned int numParams;
1764 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1765 ASSERT(queryStatus);
1766
1767 if (nativeType == GL_BOOL)
1768 {
1769 mGLState.getBooleani_v(target, index, data);
1770 }
1771 else
1772 {
1773 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1774 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001775}
1776
He Yunchao010e4db2017-03-03 14:22:06 +08001777void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1778{
1779 Buffer *buffer = mGLState.getTargetBuffer(target);
1780 QueryBufferParameteriv(buffer, pname, params);
1781}
1782
1783void Context::getFramebufferAttachmentParameteriv(GLenum target,
1784 GLenum attachment,
1785 GLenum pname,
1786 GLint *params)
1787{
1788 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1789 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1790}
1791
1792void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1793{
1794 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1795 QueryRenderbufferiv(this, renderbuffer, pname, params);
1796}
1797
1798void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1799{
1800 Texture *texture = getTargetTexture(target);
1801 QueryTexParameterfv(texture, pname, params);
1802}
1803
1804void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1805{
1806 Texture *texture = getTargetTexture(target);
1807 QueryTexParameteriv(texture, pname, params);
1808}
1809void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1810{
1811 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001812 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001813}
1814
1815void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1816{
1817 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001818 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001819}
1820
1821void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1822{
1823 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001824 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001825}
1826
1827void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1828{
1829 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001830 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001831}
1832
Jamie Madill675fe712016-12-19 13:07:54 -05001833void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001834{
Jamie Madill1b94d432015-08-07 13:23:23 -04001835 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001836 auto error = mImplementation->drawArrays(this, mode, first, count);
Jamie Madill675fe712016-12-19 13:07:54 -05001837 handleError(error);
1838 if (!error.isError())
1839 {
1840 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1841 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001842}
1843
Jamie Madill675fe712016-12-19 13:07:54 -05001844void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001845{
1846 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001847 auto error = mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount);
Jamie Madill675fe712016-12-19 13:07:54 -05001848 handleError(error);
1849 if (!error.isError())
1850 {
1851 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1852 }
Geoff Langf6db0982015-08-25 13:04:00 -04001853}
1854
Jamie Madill876429b2017-04-20 15:46:24 -04001855void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001856{
Jamie Madill1b94d432015-08-07 13:23:23 -04001857 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001858 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001859 handleError(mImplementation->drawElements(this, mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001860}
1861
Jamie Madill675fe712016-12-19 13:07:54 -05001862void Context::drawElementsInstanced(GLenum mode,
1863 GLsizei count,
1864 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001865 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001866 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001867{
1868 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001869 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001870 handleError(mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances,
1871 indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001872}
1873
Jamie Madill675fe712016-12-19 13:07:54 -05001874void Context::drawRangeElements(GLenum mode,
1875 GLuint start,
1876 GLuint end,
1877 GLsizei count,
1878 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001879 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001880{
1881 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001882 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001883 handleError(mImplementation->drawRangeElements(this, mode, start, end, count, type, indices,
1884 indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001885}
1886
Jamie Madill876429b2017-04-20 15:46:24 -04001887void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001888{
1889 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001890 handleError(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001891}
1892
Jamie Madill876429b2017-04-20 15:46:24 -04001893void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001894{
1895 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001896 handleError(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001897}
1898
Jamie Madill675fe712016-12-19 13:07:54 -05001899void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001900{
Jamie Madill675fe712016-12-19 13:07:54 -05001901 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001902}
1903
Jamie Madill675fe712016-12-19 13:07:54 -05001904void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001905{
Jamie Madill675fe712016-12-19 13:07:54 -05001906 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001907}
1908
Austin Kinross6ee1e782015-05-29 17:05:37 -07001909void Context::insertEventMarker(GLsizei length, const char *marker)
1910{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001911 ASSERT(mImplementation);
1912 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001913}
1914
1915void Context::pushGroupMarker(GLsizei length, const char *marker)
1916{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001917 ASSERT(mImplementation);
1918 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001919}
1920
1921void Context::popGroupMarker()
1922{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001923 ASSERT(mImplementation);
1924 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001925}
1926
Geoff Langd8605522016-04-13 10:19:12 -04001927void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1928{
1929 Program *programObject = getProgram(program);
1930 ASSERT(programObject);
1931
1932 programObject->bindUniformLocation(location, name);
1933}
1934
Sami Väisänena797e062016-05-12 15:23:40 +03001935void Context::setCoverageModulation(GLenum components)
1936{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001937 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001938}
1939
Sami Väisänene45e53b2016-05-25 10:36:04 +03001940void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1941{
1942 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1943}
1944
1945void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1946{
1947 GLfloat I[16];
1948 angle::Matrix<GLfloat>::setToIdentity(I);
1949
1950 mGLState.loadPathRenderingMatrix(matrixMode, I);
1951}
1952
1953void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1954{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001955 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001956 if (!pathObj)
1957 return;
1958
1959 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1960 syncRendererState();
1961
1962 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1963}
1964
1965void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1966{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001967 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001968 if (!pathObj)
1969 return;
1970
1971 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1972 syncRendererState();
1973
1974 mImplementation->stencilStrokePath(pathObj, reference, mask);
1975}
1976
1977void Context::coverFillPath(GLuint path, GLenum coverMode)
1978{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001979 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001980 if (!pathObj)
1981 return;
1982
1983 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1984 syncRendererState();
1985
1986 mImplementation->coverFillPath(pathObj, coverMode);
1987}
1988
1989void Context::coverStrokePath(GLuint path, GLenum coverMode)
1990{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001991 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001992 if (!pathObj)
1993 return;
1994
1995 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1996 syncRendererState();
1997
1998 mImplementation->coverStrokePath(pathObj, coverMode);
1999}
2000
2001void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
2002{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002003 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002004 if (!pathObj)
2005 return;
2006
2007 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2008 syncRendererState();
2009
2010 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
2011}
2012
2013void Context::stencilThenCoverStrokePath(GLuint path,
2014 GLint reference,
2015 GLuint mask,
2016 GLenum coverMode)
2017{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002018 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002019 if (!pathObj)
2020 return;
2021
2022 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2023 syncRendererState();
2024
2025 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2026}
2027
Sami Väisänend59ca052016-06-21 16:10:00 +03002028void Context::coverFillPathInstanced(GLsizei numPaths,
2029 GLenum pathNameType,
2030 const void *paths,
2031 GLuint pathBase,
2032 GLenum coverMode,
2033 GLenum transformType,
2034 const GLfloat *transformValues)
2035{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002036 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002037
2038 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2039 syncRendererState();
2040
2041 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2042}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002043
Sami Väisänend59ca052016-06-21 16:10:00 +03002044void Context::coverStrokePathInstanced(GLsizei numPaths,
2045 GLenum pathNameType,
2046 const void *paths,
2047 GLuint pathBase,
2048 GLenum coverMode,
2049 GLenum transformType,
2050 const GLfloat *transformValues)
2051{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002052 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002053
2054 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2055 syncRendererState();
2056
2057 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2058 transformValues);
2059}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002060
Sami Väisänend59ca052016-06-21 16:10:00 +03002061void Context::stencilFillPathInstanced(GLsizei numPaths,
2062 GLenum pathNameType,
2063 const void *paths,
2064 GLuint pathBase,
2065 GLenum fillMode,
2066 GLuint mask,
2067 GLenum transformType,
2068 const GLfloat *transformValues)
2069{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002070 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002071
2072 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2073 syncRendererState();
2074
2075 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2076 transformValues);
2077}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002078
Sami Väisänend59ca052016-06-21 16:10:00 +03002079void Context::stencilStrokePathInstanced(GLsizei numPaths,
2080 GLenum pathNameType,
2081 const void *paths,
2082 GLuint pathBase,
2083 GLint reference,
2084 GLuint mask,
2085 GLenum transformType,
2086 const GLfloat *transformValues)
2087{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002088 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002089
2090 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2091 syncRendererState();
2092
2093 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2094 transformValues);
2095}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002096
Sami Väisänend59ca052016-06-21 16:10:00 +03002097void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2098 GLenum pathNameType,
2099 const void *paths,
2100 GLuint pathBase,
2101 GLenum fillMode,
2102 GLuint mask,
2103 GLenum coverMode,
2104 GLenum transformType,
2105 const GLfloat *transformValues)
2106{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002107 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002108
2109 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2110 syncRendererState();
2111
2112 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2113 transformType, transformValues);
2114}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002115
Sami Väisänend59ca052016-06-21 16:10:00 +03002116void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2117 GLenum pathNameType,
2118 const void *paths,
2119 GLuint pathBase,
2120 GLint reference,
2121 GLuint mask,
2122 GLenum coverMode,
2123 GLenum transformType,
2124 const GLfloat *transformValues)
2125{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002126 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002127
2128 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2129 syncRendererState();
2130
2131 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2132 transformType, transformValues);
2133}
2134
Sami Väisänen46eaa942016-06-29 10:26:37 +03002135void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2136{
2137 auto *programObject = getProgram(program);
2138
2139 programObject->bindFragmentInputLocation(location, name);
2140}
2141
2142void Context::programPathFragmentInputGen(GLuint program,
2143 GLint location,
2144 GLenum genMode,
2145 GLint components,
2146 const GLfloat *coeffs)
2147{
2148 auto *programObject = getProgram(program);
2149
Jamie Madillbd044ed2017-06-05 12:59:21 -04002150 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002151}
2152
jchen1015015f72017-03-16 13:54:21 +08002153GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2154{
jchen10fd7c3b52017-03-21 15:36:03 +08002155 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002156 return QueryProgramResourceIndex(programObject, programInterface, name);
2157}
2158
jchen10fd7c3b52017-03-21 15:36:03 +08002159void Context::getProgramResourceName(GLuint program,
2160 GLenum programInterface,
2161 GLuint index,
2162 GLsizei bufSize,
2163 GLsizei *length,
2164 GLchar *name)
2165{
2166 const auto *programObject = getProgram(program);
2167 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2168}
2169
Jamie Madill437fa652016-05-03 15:13:24 -04002170void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002171{
Geoff Langda5777c2014-07-11 09:52:58 -04002172 if (error.isError())
2173 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002174 GLenum code = error.getCode();
2175 mErrors.insert(code);
2176 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2177 {
2178 markContextLost();
2179 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002180
2181 if (!error.getMessage().empty())
2182 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002183 auto *debug = &mGLState.getDebug();
2184 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2185 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002186 }
Geoff Langda5777c2014-07-11 09:52:58 -04002187 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002188}
2189
2190// Get one of the recorded errors and clear its flag, if any.
2191// [OpenGL ES 2.0.24] section 2.5 page 13.
2192GLenum Context::getError()
2193{
Geoff Langda5777c2014-07-11 09:52:58 -04002194 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002195 {
Geoff Langda5777c2014-07-11 09:52:58 -04002196 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002197 }
Geoff Langda5777c2014-07-11 09:52:58 -04002198 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002199 {
Geoff Langda5777c2014-07-11 09:52:58 -04002200 GLenum error = *mErrors.begin();
2201 mErrors.erase(mErrors.begin());
2202 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002203 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002204}
2205
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002206// NOTE: this function should not assume that this context is current!
2207void Context::markContextLost()
2208{
2209 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002210 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002211 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002212 mContextLostForced = true;
2213 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002214 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002215}
2216
2217bool Context::isContextLost()
2218{
2219 return mContextLost;
2220}
2221
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002222GLenum Context::getResetStatus()
2223{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002224 // Even if the application doesn't want to know about resets, we want to know
2225 // as it will allow us to skip all the calls.
2226 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002227 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002228 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002229 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002230 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002231 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002232
2233 // EXT_robustness, section 2.6: If the reset notification behavior is
2234 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2235 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2236 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002237 }
2238
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002239 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2240 // status should be returned at least once, and GL_NO_ERROR should be returned
2241 // once the device has finished resetting.
2242 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002243 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002244 ASSERT(mResetStatus == GL_NO_ERROR);
2245 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002246
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002247 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002248 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002249 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002250 }
2251 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002252 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002253 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002254 // If markContextLost was used to mark the context lost then
2255 // assume that is not recoverable, and continue to report the
2256 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002257 mResetStatus = mImplementation->getResetStatus();
2258 }
Jamie Madill893ab082014-05-16 16:56:10 -04002259
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002260 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002261}
2262
2263bool Context::isResetNotificationEnabled()
2264{
2265 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2266}
2267
Corentin Walleze3b10e82015-05-20 11:06:25 -04002268const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002269{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002270 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002271}
2272
2273EGLenum Context::getClientType() const
2274{
2275 return mClientType;
2276}
2277
2278EGLenum Context::getRenderBuffer() const
2279{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002280 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2281 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002282 {
2283 return EGL_NONE;
2284 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002285
2286 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2287 ASSERT(backAttachment != nullptr);
2288 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002289}
2290
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002291VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002292{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002293 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002294 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2295 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002296 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002297 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2298 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002299
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002300 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002301 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002302
2303 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002304}
2305
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002306TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002307{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002308 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002309 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2310 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002311 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002312 transformFeedback =
2313 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002314 transformFeedback->addRef();
2315 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002316 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002317
2318 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002319}
2320
2321bool Context::isVertexArrayGenerated(GLuint vertexArray)
2322{
Geoff Langf41a7152016-09-19 15:11:17 -04002323 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002324 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2325}
2326
2327bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2328{
Geoff Langf41a7152016-09-19 15:11:17 -04002329 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002330 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2331}
2332
Shannon Woods53a94a82014-06-24 15:20:36 -04002333void Context::detachTexture(GLuint texture)
2334{
2335 // Simple pass-through to State's detachTexture method, as textures do not require
2336 // allocation map management either here or in the resource manager at detach time.
2337 // Zero textures are held by the Context, and we don't attempt to request them from
2338 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002339 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002340}
2341
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002342void Context::detachBuffer(GLuint buffer)
2343{
Yuly Novikov5807a532015-12-03 13:01:22 -05002344 // Simple pass-through to State's detachBuffer method, since
2345 // only buffer attachments to container objects that are bound to the current context
2346 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002347
Yuly Novikov5807a532015-12-03 13:01:22 -05002348 // [OpenGL ES 3.2] section 5.1.2 page 45:
2349 // Attachments to unbound container objects, such as
2350 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2351 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002352 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002353}
2354
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002355void Context::detachFramebuffer(GLuint framebuffer)
2356{
Shannon Woods53a94a82014-06-24 15:20:36 -04002357 // Framebuffer detachment is handled by Context, because 0 is a valid
2358 // Framebuffer object, and a pointer to it must be passed from Context
2359 // to State at binding time.
2360
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002361 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002362 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2363 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2364 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002365
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002366 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002367 {
2368 bindReadFramebuffer(0);
2369 }
2370
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002371 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002372 {
2373 bindDrawFramebuffer(0);
2374 }
2375}
2376
2377void Context::detachRenderbuffer(GLuint renderbuffer)
2378{
Jamie Madilla02315b2017-02-23 14:14:47 -05002379 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002380}
2381
Jamie Madill57a89722013-07-02 11:57:03 -04002382void Context::detachVertexArray(GLuint vertexArray)
2383{
Jamie Madill77a72f62015-04-14 11:18:32 -04002384 // Vertex array detachment is handled by Context, because 0 is a valid
2385 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002386 // binding time.
2387
Jamie Madill57a89722013-07-02 11:57:03 -04002388 // [OpenGL ES 3.0.2] section 2.10 page 43:
2389 // If a vertex array object that is currently bound is deleted, the binding
2390 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002391 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002392 {
2393 bindVertexArray(0);
2394 }
2395}
2396
Geoff Langc8058452014-02-03 12:04:11 -05002397void Context::detachTransformFeedback(GLuint transformFeedback)
2398{
Corentin Walleza2257da2016-04-19 16:43:12 -04002399 // Transform feedback detachment is handled by Context, because 0 is a valid
2400 // transform feedback, and a pointer to it must be passed from Context to State at
2401 // binding time.
2402
2403 // The OpenGL specification doesn't mention what should happen when the currently bound
2404 // transform feedback object is deleted. Since it is a container object, we treat it like
2405 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002406 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002407 {
2408 bindTransformFeedback(0);
2409 }
Geoff Langc8058452014-02-03 12:04:11 -05002410}
2411
Jamie Madilldc356042013-07-19 16:36:57 -04002412void Context::detachSampler(GLuint sampler)
2413{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002414 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002415}
2416
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002417void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2418{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002419 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002420}
2421
Jamie Madille29d1672013-07-19 16:36:57 -04002422void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2423{
Geoff Langc1984ed2016-10-07 12:41:00 -04002424 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002425 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002426 SetSamplerParameteri(samplerObject, pname, param);
2427}
Jamie Madille29d1672013-07-19 16:36:57 -04002428
Geoff Langc1984ed2016-10-07 12:41:00 -04002429void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2430{
2431 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002432 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002433 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002434}
2435
2436void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2437{
Geoff Langc1984ed2016-10-07 12:41:00 -04002438 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002439 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002440 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002441}
2442
Geoff Langc1984ed2016-10-07 12:41:00 -04002443void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002444{
Geoff Langc1984ed2016-10-07 12:41:00 -04002445 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002446 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002447 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002448}
2449
Geoff Langc1984ed2016-10-07 12:41:00 -04002450void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002451{
Geoff Langc1984ed2016-10-07 12:41:00 -04002452 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002453 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002454 QuerySamplerParameteriv(samplerObject, pname, params);
2455}
Jamie Madill9675b802013-07-19 16:36:59 -04002456
Geoff Langc1984ed2016-10-07 12:41:00 -04002457void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2458{
2459 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002460 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002461 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002462}
2463
Olli Etuahof0fee072016-03-30 15:11:58 +03002464void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2465{
2466 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002467 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002468}
2469
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002470void Context::initRendererString()
2471{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002472 std::ostringstream rendererString;
2473 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002474 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002475 rendererString << ")";
2476
Geoff Langcec35902014-04-16 10:52:36 -04002477 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002478}
2479
Geoff Langc339c4e2016-11-29 10:37:36 -05002480void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002481{
Geoff Langc339c4e2016-11-29 10:37:36 -05002482 const Version &clientVersion = getClientVersion();
2483
2484 std::ostringstream versionString;
2485 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2486 << ANGLE_VERSION_STRING << ")";
2487 mVersionString = MakeStaticString(versionString.str());
2488
2489 std::ostringstream shadingLanguageVersionString;
2490 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2491 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2492 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2493 << ")";
2494 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002495}
2496
Geoff Langcec35902014-04-16 10:52:36 -04002497void Context::initExtensionStrings()
2498{
Geoff Langc339c4e2016-11-29 10:37:36 -05002499 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2500 std::ostringstream combinedStringStream;
2501 std::copy(strings.begin(), strings.end(),
2502 std::ostream_iterator<const char *>(combinedStringStream, " "));
2503 return MakeStaticString(combinedStringStream.str());
2504 };
2505
2506 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002507 for (const auto &extensionString : mExtensions.getStrings())
2508 {
2509 mExtensionStrings.push_back(MakeStaticString(extensionString));
2510 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002511 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002512
Bryan Bernhart58806562017-01-05 13:09:31 -08002513 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2514
Geoff Langc339c4e2016-11-29 10:37:36 -05002515 mRequestableExtensionStrings.clear();
2516 for (const auto &extensionInfo : GetExtensionInfoMap())
2517 {
2518 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002519 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2520 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002521 {
2522 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2523 }
2524 }
2525 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002526}
2527
Geoff Langc339c4e2016-11-29 10:37:36 -05002528const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002529{
Geoff Langc339c4e2016-11-29 10:37:36 -05002530 switch (name)
2531 {
2532 case GL_VENDOR:
2533 return reinterpret_cast<const GLubyte *>("Google Inc.");
2534
2535 case GL_RENDERER:
2536 return reinterpret_cast<const GLubyte *>(mRendererString);
2537
2538 case GL_VERSION:
2539 return reinterpret_cast<const GLubyte *>(mVersionString);
2540
2541 case GL_SHADING_LANGUAGE_VERSION:
2542 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2543
2544 case GL_EXTENSIONS:
2545 return reinterpret_cast<const GLubyte *>(mExtensionString);
2546
2547 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2548 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2549
2550 default:
2551 UNREACHABLE();
2552 return nullptr;
2553 }
Geoff Langcec35902014-04-16 10:52:36 -04002554}
2555
Geoff Langc339c4e2016-11-29 10:37:36 -05002556const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002557{
Geoff Langc339c4e2016-11-29 10:37:36 -05002558 switch (name)
2559 {
2560 case GL_EXTENSIONS:
2561 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2562
2563 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2564 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2565
2566 default:
2567 UNREACHABLE();
2568 return nullptr;
2569 }
Geoff Langcec35902014-04-16 10:52:36 -04002570}
2571
2572size_t Context::getExtensionStringCount() const
2573{
2574 return mExtensionStrings.size();
2575}
2576
Geoff Langc339c4e2016-11-29 10:37:36 -05002577void Context::requestExtension(const char *name)
2578{
2579 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2580 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2581 const auto &extension = extensionInfos.at(name);
2582 ASSERT(extension.Requestable);
2583
2584 if (mExtensions.*(extension.ExtensionsMember))
2585 {
2586 // Extension already enabled
2587 return;
2588 }
2589
2590 mExtensions.*(extension.ExtensionsMember) = true;
2591 updateCaps();
2592 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002593
Jamie Madill2f348d22017-06-05 10:50:59 -04002594 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2595 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002596
2597 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2598 // formats renderable or sampleable.
2599 mState.mTextures->invalidateTextureComplenessCache();
2600 for (auto &zeroTexture : mZeroTextures)
2601 {
2602 zeroTexture.second->invalidateCompletenessCache();
2603 }
2604
2605 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002606}
2607
2608size_t Context::getRequestableExtensionStringCount() const
2609{
2610 return mRequestableExtensionStrings.size();
2611}
2612
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002613void Context::beginTransformFeedback(GLenum primitiveMode)
2614{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002615 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002616 ASSERT(transformFeedback != nullptr);
2617 ASSERT(!transformFeedback->isPaused());
2618
Jamie Madill6c1f6712017-02-14 19:08:04 -05002619 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002620}
2621
2622bool Context::hasActiveTransformFeedback(GLuint program) const
2623{
2624 for (auto pair : mTransformFeedbackMap)
2625 {
2626 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2627 {
2628 return true;
2629 }
2630 }
2631 return false;
2632}
2633
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002634void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002635{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002636 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002637
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002638 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002639
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002640 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002641
Geoff Langeb66a6e2016-10-31 13:06:12 -04002642 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002643 {
2644 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002645 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002646 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002647 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002648 }
2649
Geoff Langeb66a6e2016-10-31 13:06:12 -04002650 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002651 {
2652 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002653 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002654 }
2655
Jamie Madill00ed7a12016-05-19 13:13:38 -04002656 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002657 mExtensions.bindUniformLocation = true;
2658 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002659 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002660 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002661 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002662
2663 // Enable the no error extension if the context was created with the flag.
2664 mExtensions.noError = mSkipValidation;
2665
Corentin Wallezccab69d2017-01-27 16:57:15 -05002666 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002667 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002668
Geoff Lang70d0f492015-12-10 17:45:46 -05002669 // Explicitly enable GL_KHR_debug
2670 mExtensions.debug = true;
2671 mExtensions.maxDebugMessageLength = 1024;
2672 mExtensions.maxDebugLoggedMessages = 1024;
2673 mExtensions.maxDebugGroupStackDepth = 1024;
2674 mExtensions.maxLabelLength = 1024;
2675
Geoff Langff5b2d52016-09-07 11:32:23 -04002676 // Explicitly enable GL_ANGLE_robust_client_memory
2677 mExtensions.robustClientMemory = true;
2678
Jamie Madille08a1d32017-03-07 17:24:06 -05002679 // Determine robust resource init availability from EGL.
2680 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002681 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002682
Geoff Lang301d1612014-07-09 10:34:37 -04002683 // Apply implementation limits
2684 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002685 mCaps.maxVertexAttribBindings =
2686 getClientVersion() < ES_3_1
2687 ? mCaps.maxVertexAttributes
2688 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2689
Jamie Madill231c7f52017-04-26 13:45:37 -04002690 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2691 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2692 mCaps.maxVertexOutputComponents =
2693 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002694
Jamie Madill231c7f52017-04-26 13:45:37 -04002695 mCaps.maxFragmentInputComponents =
2696 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002697
Geoff Langc287ea62016-09-16 14:46:51 -04002698 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002699 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002700 for (const auto &extensionInfo : GetExtensionInfoMap())
2701 {
2702 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002703 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002704 {
2705 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2706 }
2707 }
2708
2709 // Generate texture caps
2710 updateCaps();
2711}
2712
2713void Context::updateCaps()
2714{
Geoff Lang900013c2014-07-07 11:32:19 -04002715 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002716 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002717
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002718 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002719 {
Geoff Langca271392017-04-05 12:30:00 -04002720 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002721 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002722
Geoff Langca271392017-04-05 12:30:00 -04002723 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002724
Geoff Lang0d8b7242015-09-09 14:56:53 -04002725 // Update the format caps based on the client version and extensions.
2726 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2727 // ES3.
2728 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002729 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002730 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002731 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002732 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002733 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002734
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002735 // OpenGL ES does not support multisampling with non-rendererable formats
2736 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho3cd0dd32017-06-06 14:43:30 +03002737 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002738 (getClientVersion() < ES_3_1 &&
2739 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002740 {
Geoff Langd87878e2014-09-19 15:42:59 -04002741 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002742 }
Olli Etuaho3cd0dd32017-06-06 14:43:30 +03002743 else
2744 {
2745 // We may have limited the max samples for some required renderbuffer formats due to
2746 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2747 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2748
2749 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2750 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2751 // exception of signed and unsigned integer formats."
2752 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2753 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2754 {
2755 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2756 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2757 }
2758
2759 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2760 if (getClientVersion() >= ES_3_1)
2761 {
2762 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2763 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2764 // the exception that the signed and unsigned integer formats are required only to
2765 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2766 // multisamples, which must be at least one."
2767 if (formatInfo.componentType == GL_INT ||
2768 formatInfo.componentType == GL_UNSIGNED_INT)
2769 {
2770 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2771 }
2772
2773 // GLES 3.1 section 19.3.1.
2774 if (formatCaps.texturable)
2775 {
2776 if (formatInfo.depthBits > 0)
2777 {
2778 mCaps.maxDepthTextureSamples =
2779 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2780 }
2781 else if (formatInfo.redBits > 0)
2782 {
2783 mCaps.maxColorTextureSamples =
2784 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2785 }
2786 }
2787 }
2788 }
Geoff Langd87878e2014-09-19 15:42:59 -04002789
2790 if (formatCaps.texturable && formatInfo.compressed)
2791 {
Geoff Langca271392017-04-05 12:30:00 -04002792 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002793 }
2794
Geoff Langca271392017-04-05 12:30:00 -04002795 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002796 }
2797}
2798
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002799void Context::initWorkarounds()
2800{
2801 // 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 Madilldfde6ab2016-06-09 07:07:18 -07002808 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002809 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002810 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002811 mGLState.syncDirtyObjects(this);
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 Madilldfde6ab2016-06-09 07:07:18 -07002817 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002818 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002820 mGLState.syncDirtyObjects(this, objectMask);
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 Madilldfde6ab2016-06-09 07:07:18 -07002900 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002901 ASSERT(framebufferObject);
2902
2903 Rectangle area(x, y, width, height);
Jamie Madillc564c072017-06-01 12:45:42 -04002904 handleError(framebufferObject->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 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002998 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2999 {
3000 ASSERT(level == 0);
3001 index = ImageIndex::Make2DMultisample();
3002 }
Jamie Madillc29968b2016-01-20 11:17:23 -05003003 else
3004 {
3005 ASSERT(IsCubeMapTextureTarget(textarget));
3006 index = ImageIndex::MakeCube(textarget, level);
3007 }
3008
Jamie Madilla02315b2017-02-23 14:14:47 -05003009 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003010 }
3011 else
3012 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003013 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003014 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003015
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003016 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003017}
3018
3019void Context::framebufferRenderbuffer(GLenum target,
3020 GLenum attachment,
3021 GLenum renderbuffertarget,
3022 GLuint renderbuffer)
3023{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003024 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003025 ASSERT(framebuffer);
3026
3027 if (renderbuffer != 0)
3028 {
3029 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003030
3031 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003032 renderbufferObject);
3033 }
3034 else
3035 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003036 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003037 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003038
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003039 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003040}
3041
3042void Context::framebufferTextureLayer(GLenum target,
3043 GLenum attachment,
3044 GLuint texture,
3045 GLint level,
3046 GLint layer)
3047{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003048 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003049 ASSERT(framebuffer);
3050
3051 if (texture != 0)
3052 {
3053 Texture *textureObject = getTexture(texture);
3054
3055 ImageIndex index = ImageIndex::MakeInvalid();
3056
3057 if (textureObject->getTarget() == GL_TEXTURE_3D)
3058 {
3059 index = ImageIndex::Make3D(level, layer);
3060 }
3061 else
3062 {
3063 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3064 index = ImageIndex::Make2DArray(level, layer);
3065 }
3066
Jamie Madilla02315b2017-02-23 14:14:47 -05003067 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003068 }
3069 else
3070 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003071 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003072 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003073
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003074 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003075}
3076
3077void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3078{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003079 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003080 ASSERT(framebuffer);
3081 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003082 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003083}
3084
3085void Context::readBuffer(GLenum mode)
3086{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003087 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003088 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003089 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003090}
3091
3092void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3093{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003094 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003095 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003096
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003097 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003098 ASSERT(framebuffer);
3099
3100 // The specification isn't clear what should be done when the framebuffer isn't complete.
3101 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003102 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003103}
3104
3105void Context::invalidateFramebuffer(GLenum target,
3106 GLsizei numAttachments,
3107 const GLenum *attachments)
3108{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003109 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003110 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003111
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003112 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003113 ASSERT(framebuffer);
3114
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003115 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003116 {
Jamie Madill437fa652016-05-03 15:13:24 -04003117 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003118 }
Jamie Madill437fa652016-05-03 15:13:24 -04003119
Jamie Madill4928b7c2017-06-20 12:57:39 -04003120 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003121}
3122
3123void Context::invalidateSubFramebuffer(GLenum target,
3124 GLsizei numAttachments,
3125 const GLenum *attachments,
3126 GLint x,
3127 GLint y,
3128 GLsizei width,
3129 GLsizei height)
3130{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003131 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003132 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003133
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003134 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003135 ASSERT(framebuffer);
3136
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003137 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003138 {
Jamie Madill437fa652016-05-03 15:13:24 -04003139 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003140 }
Jamie Madill437fa652016-05-03 15:13:24 -04003141
3142 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003143 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003144}
3145
Jamie Madill73a84962016-02-12 09:27:23 -05003146void Context::texImage2D(GLenum target,
3147 GLint level,
3148 GLint internalformat,
3149 GLsizei width,
3150 GLsizei height,
3151 GLint border,
3152 GLenum format,
3153 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003154 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003155{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003156 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003157
3158 Extents size(width, height, 1);
3159 Texture *texture =
3160 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003161 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3162 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003163}
3164
3165void Context::texImage3D(GLenum target,
3166 GLint level,
3167 GLint internalformat,
3168 GLsizei width,
3169 GLsizei height,
3170 GLsizei depth,
3171 GLint border,
3172 GLenum format,
3173 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003174 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003175{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003176 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003177
3178 Extents size(width, height, depth);
3179 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003180 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3181 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003182}
3183
3184void Context::texSubImage2D(GLenum target,
3185 GLint level,
3186 GLint xoffset,
3187 GLint yoffset,
3188 GLsizei width,
3189 GLsizei height,
3190 GLenum format,
3191 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003192 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003193{
3194 // Zero sized uploads are valid but no-ops
3195 if (width == 0 || height == 0)
3196 {
3197 return;
3198 }
3199
Jamie Madillad9f24e2016-02-12 09:27:24 -05003200 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003201
3202 Box area(xoffset, yoffset, 0, width, height, 1);
3203 Texture *texture =
3204 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003205 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3206 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003207}
3208
3209void Context::texSubImage3D(GLenum target,
3210 GLint level,
3211 GLint xoffset,
3212 GLint yoffset,
3213 GLint zoffset,
3214 GLsizei width,
3215 GLsizei height,
3216 GLsizei depth,
3217 GLenum format,
3218 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003219 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003220{
3221 // Zero sized uploads are valid but no-ops
3222 if (width == 0 || height == 0 || depth == 0)
3223 {
3224 return;
3225 }
3226
Jamie Madillad9f24e2016-02-12 09:27:24 -05003227 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003228
3229 Box area(xoffset, yoffset, zoffset, width, height, depth);
3230 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003231 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3232 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003233}
3234
3235void Context::compressedTexImage2D(GLenum target,
3236 GLint level,
3237 GLenum internalformat,
3238 GLsizei width,
3239 GLsizei height,
3240 GLint border,
3241 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003242 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003243{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003244 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003245
3246 Extents size(width, height, 1);
3247 Texture *texture =
3248 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003249 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003250 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003251 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003252}
3253
3254void Context::compressedTexImage3D(GLenum target,
3255 GLint level,
3256 GLenum internalformat,
3257 GLsizei width,
3258 GLsizei height,
3259 GLsizei depth,
3260 GLint border,
3261 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003262 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003263{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003264 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003265
3266 Extents size(width, height, depth);
3267 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003268 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003269 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003270 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003271}
3272
3273void Context::compressedTexSubImage2D(GLenum target,
3274 GLint level,
3275 GLint xoffset,
3276 GLint yoffset,
3277 GLsizei width,
3278 GLsizei height,
3279 GLenum format,
3280 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003281 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003282{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003283 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003284
3285 Box area(xoffset, yoffset, 0, width, height, 1);
3286 Texture *texture =
3287 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003288 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003289 format, imageSize,
3290 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003291}
3292
3293void Context::compressedTexSubImage3D(GLenum target,
3294 GLint level,
3295 GLint xoffset,
3296 GLint yoffset,
3297 GLint zoffset,
3298 GLsizei width,
3299 GLsizei height,
3300 GLsizei depth,
3301 GLenum format,
3302 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003303 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003304{
3305 // Zero sized uploads are valid but no-ops
3306 if (width == 0 || height == 0)
3307 {
3308 return;
3309 }
3310
Jamie Madillad9f24e2016-02-12 09:27:24 -05003311 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003312
3313 Box area(xoffset, yoffset, zoffset, width, height, depth);
3314 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003315 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003316 format, imageSize,
3317 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003318}
3319
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003320void Context::generateMipmap(GLenum target)
3321{
3322 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003323 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003324}
3325
Geoff Lang97073d12016-04-20 10:42:34 -07003326void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003327 GLint sourceLevel,
3328 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003329 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003330 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003331 GLint internalFormat,
3332 GLenum destType,
3333 GLboolean unpackFlipY,
3334 GLboolean unpackPremultiplyAlpha,
3335 GLboolean unpackUnmultiplyAlpha)
3336{
3337 syncStateForTexImage();
3338
3339 gl::Texture *sourceTexture = getTexture(sourceId);
3340 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003341 handleError(destTexture->copyTexture(
3342 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3343 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003344}
3345
3346void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003347 GLint sourceLevel,
3348 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003349 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003350 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003351 GLint xoffset,
3352 GLint yoffset,
3353 GLint x,
3354 GLint y,
3355 GLsizei width,
3356 GLsizei height,
3357 GLboolean unpackFlipY,
3358 GLboolean unpackPremultiplyAlpha,
3359 GLboolean unpackUnmultiplyAlpha)
3360{
3361 // Zero sized copies are valid but no-ops
3362 if (width == 0 || height == 0)
3363 {
3364 return;
3365 }
3366
3367 syncStateForTexImage();
3368
3369 gl::Texture *sourceTexture = getTexture(sourceId);
3370 gl::Texture *destTexture = getTexture(destId);
3371 Offset offset(xoffset, yoffset, 0);
3372 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003373 handleError(destTexture->copySubTexture(
3374 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3375 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003376}
3377
Geoff Lang47110bf2016-04-20 11:13:22 -07003378void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3379{
3380 syncStateForTexImage();
3381
3382 gl::Texture *sourceTexture = getTexture(sourceId);
3383 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003384 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003385}
3386
Geoff Lang496c02d2016-10-20 11:38:11 -07003387void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003388{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003390 ASSERT(buffer);
3391
Geoff Lang496c02d2016-10-20 11:38:11 -07003392 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003393}
3394
Jamie Madill876429b2017-04-20 15:46:24 -04003395void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003396{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003397 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003398 ASSERT(buffer);
3399
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003400 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003401 if (error.isError())
3402 {
Jamie Madill437fa652016-05-03 15:13:24 -04003403 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003404 return nullptr;
3405 }
3406
3407 return buffer->getMapPointer();
3408}
3409
3410GLboolean Context::unmapBuffer(GLenum target)
3411{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003412 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003413 ASSERT(buffer);
3414
3415 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003416 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003417 if (error.isError())
3418 {
Jamie Madill437fa652016-05-03 15:13:24 -04003419 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003420 return GL_FALSE;
3421 }
3422
3423 return result;
3424}
3425
Jamie Madill876429b2017-04-20 15:46:24 -04003426void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003427{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003428 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003429 ASSERT(buffer);
3430
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003431 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003432 if (error.isError())
3433 {
Jamie Madill437fa652016-05-03 15:13:24 -04003434 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003435 return nullptr;
3436 }
3437
3438 return buffer->getMapPointer();
3439}
3440
3441void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3442{
3443 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3444}
3445
Jamie Madillad9f24e2016-02-12 09:27:24 -05003446void Context::syncStateForReadPixels()
3447{
3448 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3449}
3450
3451void Context::syncStateForTexImage()
3452{
3453 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3454}
3455
3456void Context::syncStateForClear()
3457{
3458 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3459}
3460
3461void Context::syncStateForBlit()
3462{
3463 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3464}
3465
Jamie Madillc20ab272016-06-09 07:20:46 -07003466void Context::activeTexture(GLenum texture)
3467{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003468 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003469}
3470
Jamie Madill876429b2017-04-20 15:46:24 -04003471void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003472{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003473 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003474}
3475
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003476void Context::blendEquation(GLenum mode)
3477{
3478 mGLState.setBlendEquation(mode, mode);
3479}
3480
Jamie Madillc20ab272016-06-09 07:20:46 -07003481void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3482{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484}
3485
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003486void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3487{
3488 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3489}
3490
Jamie Madillc20ab272016-06-09 07:20:46 -07003491void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3492{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003493 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003494}
3495
Jamie Madill876429b2017-04-20 15:46:24 -04003496void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003497{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003498 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003499}
3500
Jamie Madill876429b2017-04-20 15:46:24 -04003501void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003502{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003503 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003504}
3505
3506void Context::clearStencil(GLint s)
3507{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003509}
3510
3511void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3512{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003513 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003514}
3515
3516void Context::cullFace(GLenum mode)
3517{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003518 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003519}
3520
3521void Context::depthFunc(GLenum func)
3522{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003523 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003524}
3525
3526void Context::depthMask(GLboolean flag)
3527{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003528 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003529}
3530
Jamie Madill876429b2017-04-20 15:46:24 -04003531void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003532{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003533 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003534}
3535
3536void Context::disable(GLenum cap)
3537{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003538 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003539}
3540
3541void Context::disableVertexAttribArray(GLuint index)
3542{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003543 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003544}
3545
3546void Context::enable(GLenum cap)
3547{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003548 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003549}
3550
3551void Context::enableVertexAttribArray(GLuint index)
3552{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003553 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003554}
3555
3556void Context::frontFace(GLenum mode)
3557{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003558 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003559}
3560
3561void Context::hint(GLenum target, GLenum mode)
3562{
3563 switch (target)
3564 {
3565 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003566 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003567 break;
3568
3569 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003570 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003571 break;
3572
3573 default:
3574 UNREACHABLE();
3575 return;
3576 }
3577}
3578
3579void Context::lineWidth(GLfloat width)
3580{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003581 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003582}
3583
3584void Context::pixelStorei(GLenum pname, GLint param)
3585{
3586 switch (pname)
3587 {
3588 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003589 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003590 break;
3591
3592 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003593 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003594 break;
3595
3596 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003597 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003598 break;
3599
3600 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003601 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003602 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003603 break;
3604
3605 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003606 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003607 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003608 break;
3609
3610 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003611 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003612 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003613 break;
3614
3615 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003616 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003617 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003618 break;
3619
3620 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003621 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003622 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003623 break;
3624
3625 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003626 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003627 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003628 break;
3629
3630 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003631 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003632 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003633 break;
3634
3635 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003636 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003637 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003638 break;
3639
3640 default:
3641 UNREACHABLE();
3642 return;
3643 }
3644}
3645
3646void Context::polygonOffset(GLfloat factor, GLfloat units)
3647{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003648 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003649}
3650
Jamie Madill876429b2017-04-20 15:46:24 -04003651void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003652{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003653 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003654}
3655
3656void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3657{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003658 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003659}
3660
3661void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3662{
3663 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3664 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003665 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003666 }
3667
3668 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3669 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003670 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003671 }
3672}
3673
3674void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3675{
3676 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3677 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003678 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003679 }
3680
3681 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3682 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003683 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003684 }
3685}
3686
3687void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3688{
3689 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3690 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003691 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003692 }
3693
3694 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3695 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003696 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003697 }
3698}
3699
3700void Context::vertexAttrib1f(GLuint index, GLfloat x)
3701{
3702 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003703 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003704}
3705
3706void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3707{
3708 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003709 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003710}
3711
3712void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3713{
3714 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003715 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003716}
3717
3718void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3719{
3720 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003721 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003722}
3723
3724void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3725{
3726 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003727 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003728}
3729
3730void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3731{
3732 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003733 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003734}
3735
3736void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3737{
3738 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003739 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003740}
3741
3742void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3743{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003744 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003745}
3746
3747void Context::vertexAttribPointer(GLuint index,
3748 GLint size,
3749 GLenum type,
3750 GLboolean normalized,
3751 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003752 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003753{
Jamie Madill4928b7c2017-06-20 12:57:39 -04003754 mGLState.setVertexAttribState(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3755 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003756}
3757
Shao80957d92017-02-20 21:25:59 +08003758void Context::vertexAttribFormat(GLuint attribIndex,
3759 GLint size,
3760 GLenum type,
3761 GLboolean normalized,
3762 GLuint relativeOffset)
3763{
3764 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3765 relativeOffset);
3766}
3767
3768void Context::vertexAttribIFormat(GLuint attribIndex,
3769 GLint size,
3770 GLenum type,
3771 GLuint relativeOffset)
3772{
3773 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3774}
3775
3776void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3777{
3778 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3779}
3780
3781void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3782{
3783 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3784}
3785
Jamie Madillc20ab272016-06-09 07:20:46 -07003786void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3787{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003788 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003789}
3790
3791void Context::vertexAttribIPointer(GLuint index,
3792 GLint size,
3793 GLenum type,
3794 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003795 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003796{
Jamie Madill4928b7c2017-06-20 12:57:39 -04003797 mGLState.setVertexAttribState(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3798 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003799}
3800
3801void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3802{
3803 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003804 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003805}
3806
3807void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3808{
3809 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003810 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003811}
3812
3813void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3814{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003815 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003816}
3817
3818void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3819{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003820 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003821}
3822
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003823void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3824{
3825 const VertexAttribCurrentValueData &currentValues =
3826 getGLState().getVertexAttribCurrentValue(index);
3827 const VertexArray *vao = getGLState().getVertexArray();
3828 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3829 currentValues, pname, params);
3830}
3831
3832void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3833{
3834 const VertexAttribCurrentValueData &currentValues =
3835 getGLState().getVertexAttribCurrentValue(index);
3836 const VertexArray *vao = getGLState().getVertexArray();
3837 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3838 currentValues, pname, params);
3839}
3840
3841void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3842{
3843 const VertexAttribCurrentValueData &currentValues =
3844 getGLState().getVertexAttribCurrentValue(index);
3845 const VertexArray *vao = getGLState().getVertexArray();
3846 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3847 currentValues, pname, params);
3848}
3849
3850void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3851{
3852 const VertexAttribCurrentValueData &currentValues =
3853 getGLState().getVertexAttribCurrentValue(index);
3854 const VertexArray *vao = getGLState().getVertexArray();
3855 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3856 currentValues, pname, params);
3857}
3858
Jamie Madill876429b2017-04-20 15:46:24 -04003859void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003860{
3861 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3862 QueryVertexAttribPointerv(attrib, pname, pointer);
3863}
3864
Jamie Madillc20ab272016-06-09 07:20:46 -07003865void Context::debugMessageControl(GLenum source,
3866 GLenum type,
3867 GLenum severity,
3868 GLsizei count,
3869 const GLuint *ids,
3870 GLboolean enabled)
3871{
3872 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003873 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3874 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003875}
3876
3877void Context::debugMessageInsert(GLenum source,
3878 GLenum type,
3879 GLuint id,
3880 GLenum severity,
3881 GLsizei length,
3882 const GLchar *buf)
3883{
3884 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003885 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003886}
3887
3888void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3889{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003890 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003891}
3892
3893GLuint Context::getDebugMessageLog(GLuint count,
3894 GLsizei bufSize,
3895 GLenum *sources,
3896 GLenum *types,
3897 GLuint *ids,
3898 GLenum *severities,
3899 GLsizei *lengths,
3900 GLchar *messageLog)
3901{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003902 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3903 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003904}
3905
3906void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3907{
3908 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003909 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003910}
3911
3912void Context::popDebugGroup()
3913{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003914 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003915}
3916
Jamie Madill876429b2017-04-20 15:46:24 -04003917void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003918{
3919 Buffer *buffer = mGLState.getTargetBuffer(target);
3920 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003921 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003922}
3923
Jamie Madill876429b2017-04-20 15:46:24 -04003924void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003925{
3926 if (data == nullptr)
3927 {
3928 return;
3929 }
3930
3931 Buffer *buffer = mGLState.getTargetBuffer(target);
3932 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003933 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003934}
3935
Jamie Madillef300b12016-10-07 15:12:09 -04003936void Context::attachShader(GLuint program, GLuint shader)
3937{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003938 auto programObject = mState.mShaderPrograms->getProgram(program);
3939 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003940 ASSERT(programObject && shaderObject);
3941 programObject->attachShader(shaderObject);
3942}
3943
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003944const Workarounds &Context::getWorkarounds() const
3945{
3946 return mWorkarounds;
3947}
3948
Jamie Madillb0817d12016-11-01 15:48:31 -04003949void Context::copyBufferSubData(GLenum readTarget,
3950 GLenum writeTarget,
3951 GLintptr readOffset,
3952 GLintptr writeOffset,
3953 GLsizeiptr size)
3954{
3955 // if size is zero, the copy is a successful no-op
3956 if (size == 0)
3957 {
3958 return;
3959 }
3960
3961 // TODO(jmadill): cache these.
3962 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3963 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3964
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003965 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003966}
3967
Jamie Madill01a80ee2016-11-07 12:06:18 -05003968void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3969{
3970 Program *programObject = getProgram(program);
3971 // TODO(jmadill): Re-use this from the validation if possible.
3972 ASSERT(programObject);
3973 programObject->bindAttributeLocation(index, name);
3974}
3975
3976void Context::bindBuffer(GLenum target, GLuint buffer)
3977{
3978 switch (target)
3979 {
3980 case GL_ARRAY_BUFFER:
3981 bindArrayBuffer(buffer);
3982 break;
3983 case GL_ELEMENT_ARRAY_BUFFER:
3984 bindElementArrayBuffer(buffer);
3985 break;
3986 case GL_COPY_READ_BUFFER:
3987 bindCopyReadBuffer(buffer);
3988 break;
3989 case GL_COPY_WRITE_BUFFER:
3990 bindCopyWriteBuffer(buffer);
3991 break;
3992 case GL_PIXEL_PACK_BUFFER:
3993 bindPixelPackBuffer(buffer);
3994 break;
3995 case GL_PIXEL_UNPACK_BUFFER:
3996 bindPixelUnpackBuffer(buffer);
3997 break;
3998 case GL_UNIFORM_BUFFER:
3999 bindGenericUniformBuffer(buffer);
4000 break;
4001 case GL_TRANSFORM_FEEDBACK_BUFFER:
4002 bindGenericTransformFeedbackBuffer(buffer);
4003 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004004 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004005 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004006 break;
4007 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004008 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004009 break;
4010 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004011 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004012 break;
4013 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004014 if (buffer != 0)
4015 {
4016 // Binding buffers to this binding point is not implemented yet.
4017 UNIMPLEMENTED();
4018 }
Geoff Lang3b573612016-10-31 14:08:10 -04004019 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004020
4021 default:
4022 UNREACHABLE();
4023 break;
4024 }
4025}
4026
Jiajia Qin6eafb042016-12-27 17:04:07 +08004027void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4028{
4029 bindBufferRange(target, index, buffer, 0, 0);
4030}
4031
4032void Context::bindBufferRange(GLenum target,
4033 GLuint index,
4034 GLuint buffer,
4035 GLintptr offset,
4036 GLsizeiptr size)
4037{
4038 switch (target)
4039 {
4040 case GL_TRANSFORM_FEEDBACK_BUFFER:
4041 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4042 bindGenericTransformFeedbackBuffer(buffer);
4043 break;
4044 case GL_UNIFORM_BUFFER:
4045 bindIndexedUniformBuffer(buffer, index, offset, size);
4046 bindGenericUniformBuffer(buffer);
4047 break;
4048 case GL_ATOMIC_COUNTER_BUFFER:
4049 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4050 bindGenericAtomicCounterBuffer(buffer);
4051 break;
4052 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004053 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4054 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004055 break;
4056 default:
4057 UNREACHABLE();
4058 break;
4059 }
4060}
4061
Jamie Madill01a80ee2016-11-07 12:06:18 -05004062void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4063{
4064 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4065 {
4066 bindReadFramebuffer(framebuffer);
4067 }
4068
4069 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4070 {
4071 bindDrawFramebuffer(framebuffer);
4072 }
4073}
4074
4075void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4076{
4077 ASSERT(target == GL_RENDERBUFFER);
4078 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004079 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004080 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004081}
4082
JiangYizhoubddc46b2016-12-09 09:50:51 +08004083void Context::texStorage2DMultisample(GLenum target,
4084 GLsizei samples,
4085 GLenum internalformat,
4086 GLsizei width,
4087 GLsizei height,
4088 GLboolean fixedsamplelocations)
4089{
4090 Extents size(width, height, 1);
4091 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004092 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004093 fixedsamplelocations));
4094}
4095
4096void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4097{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004098 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004099 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4100
4101 switch (pname)
4102 {
4103 case GL_SAMPLE_POSITION:
4104 handleError(framebuffer->getSamplePosition(index, val));
4105 break;
4106 default:
4107 UNREACHABLE();
4108 }
4109}
4110
Jamie Madille8fb6402017-02-14 17:56:40 -05004111void Context::renderbufferStorage(GLenum target,
4112 GLenum internalformat,
4113 GLsizei width,
4114 GLsizei height)
4115{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004116 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4117 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4118
Jamie Madille8fb6402017-02-14 17:56:40 -05004119 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004120 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004121}
4122
4123void Context::renderbufferStorageMultisample(GLenum target,
4124 GLsizei samples,
4125 GLenum internalformat,
4126 GLsizei width,
4127 GLsizei height)
4128{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004129 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4130 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004131
4132 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004133 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004134 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004135}
4136
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004137void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4138{
4139 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004140 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004141}
4142
JiangYizhoue18e6392017-02-20 10:32:23 +08004143void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4144{
4145 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4146 QueryFramebufferParameteriv(framebuffer, pname, params);
4147}
4148
4149void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4150{
4151 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4152 SetFramebufferParameteri(framebuffer, pname, param);
4153}
4154
Jamie Madille14951e2017-03-09 18:55:16 -05004155Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4156{
4157 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4158 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004159 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004160 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004161 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004162}
4163
Xinghua Cao2b396592017-03-29 15:36:04 +08004164void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4165{
4166 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4167 {
4168 return;
4169 }
4170
Jamie Madillfe548342017-06-19 11:13:24 -04004171 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004172}
4173
JiangYizhou165361c2017-06-07 14:56:57 +08004174void Context::texStorage2D(GLenum target,
4175 GLsizei levels,
4176 GLenum internalFormat,
4177 GLsizei width,
4178 GLsizei height)
4179{
4180 Extents size(width, height, 1);
4181 Texture *texture = getTargetTexture(target);
4182 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4183}
4184
4185void Context::texStorage3D(GLenum target,
4186 GLsizei levels,
4187 GLenum internalFormat,
4188 GLsizei width,
4189 GLsizei height,
4190 GLsizei depth)
4191{
4192 Extents size(width, height, depth);
4193 Texture *texture = getTargetTexture(target);
4194 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4195}
4196
Jamie Madillc1d770e2017-04-13 17:31:24 -04004197GLenum Context::checkFramebufferStatus(GLenum target)
4198{
4199 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4200 ASSERT(framebuffer);
4201
4202 return framebuffer->checkStatus(this);
4203}
4204
4205void Context::compileShader(GLuint shader)
4206{
4207 Shader *shaderObject = GetValidShader(this, shader);
4208 if (!shaderObject)
4209 {
4210 return;
4211 }
4212 shaderObject->compile(this);
4213}
4214
4215void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4216{
4217 for (int i = 0; i < n; i++)
4218 {
4219 deleteBuffer(buffers[i]);
4220 }
4221}
4222
4223void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4224{
4225 for (int i = 0; i < n; i++)
4226 {
4227 if (framebuffers[i] != 0)
4228 {
4229 deleteFramebuffer(framebuffers[i]);
4230 }
4231 }
4232}
4233
4234void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4235{
4236 for (int i = 0; i < n; i++)
4237 {
4238 deleteRenderbuffer(renderbuffers[i]);
4239 }
4240}
4241
4242void Context::deleteTextures(GLsizei n, const GLuint *textures)
4243{
4244 for (int i = 0; i < n; i++)
4245 {
4246 if (textures[i] != 0)
4247 {
4248 deleteTexture(textures[i]);
4249 }
4250 }
4251}
4252
4253void Context::detachShader(GLuint program, GLuint shader)
4254{
4255 Program *programObject = getProgram(program);
4256 ASSERT(programObject);
4257
4258 Shader *shaderObject = getShader(shader);
4259 ASSERT(shaderObject);
4260
4261 programObject->detachShader(this, shaderObject);
4262}
4263
4264void Context::genBuffers(GLsizei n, GLuint *buffers)
4265{
4266 for (int i = 0; i < n; i++)
4267 {
4268 buffers[i] = createBuffer();
4269 }
4270}
4271
4272void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4273{
4274 for (int i = 0; i < n; i++)
4275 {
4276 framebuffers[i] = createFramebuffer();
4277 }
4278}
4279
4280void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4281{
4282 for (int i = 0; i < n; i++)
4283 {
4284 renderbuffers[i] = createRenderbuffer();
4285 }
4286}
4287
4288void Context::genTextures(GLsizei n, GLuint *textures)
4289{
4290 for (int i = 0; i < n; i++)
4291 {
4292 textures[i] = createTexture();
4293 }
4294}
4295
4296void Context::getActiveAttrib(GLuint program,
4297 GLuint index,
4298 GLsizei bufsize,
4299 GLsizei *length,
4300 GLint *size,
4301 GLenum *type,
4302 GLchar *name)
4303{
4304 Program *programObject = getProgram(program);
4305 ASSERT(programObject);
4306 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4307}
4308
4309void Context::getActiveUniform(GLuint program,
4310 GLuint index,
4311 GLsizei bufsize,
4312 GLsizei *length,
4313 GLint *size,
4314 GLenum *type,
4315 GLchar *name)
4316{
4317 Program *programObject = getProgram(program);
4318 ASSERT(programObject);
4319 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4320}
4321
4322void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4323{
4324 Program *programObject = getProgram(program);
4325 ASSERT(programObject);
4326 programObject->getAttachedShaders(maxcount, count, shaders);
4327}
4328
4329GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4330{
4331 Program *programObject = getProgram(program);
4332 ASSERT(programObject);
4333 return programObject->getAttributeLocation(name);
4334}
4335
4336void Context::getBooleanv(GLenum pname, GLboolean *params)
4337{
4338 GLenum nativeType;
4339 unsigned int numParams = 0;
4340 getQueryParameterInfo(pname, &nativeType, &numParams);
4341
4342 if (nativeType == GL_BOOL)
4343 {
4344 getBooleanvImpl(pname, params);
4345 }
4346 else
4347 {
4348 CastStateValues(this, nativeType, pname, numParams, params);
4349 }
4350}
4351
4352void Context::getFloatv(GLenum pname, GLfloat *params)
4353{
4354 GLenum nativeType;
4355 unsigned int numParams = 0;
4356 getQueryParameterInfo(pname, &nativeType, &numParams);
4357
4358 if (nativeType == GL_FLOAT)
4359 {
4360 getFloatvImpl(pname, params);
4361 }
4362 else
4363 {
4364 CastStateValues(this, nativeType, pname, numParams, params);
4365 }
4366}
4367
4368void Context::getIntegerv(GLenum pname, GLint *params)
4369{
4370 GLenum nativeType;
4371 unsigned int numParams = 0;
4372 getQueryParameterInfo(pname, &nativeType, &numParams);
4373
4374 if (nativeType == GL_INT)
4375 {
4376 getIntegervImpl(pname, params);
4377 }
4378 else
4379 {
4380 CastStateValues(this, nativeType, pname, numParams, params);
4381 }
4382}
4383
4384void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4385{
4386 Program *programObject = getProgram(program);
4387 ASSERT(programObject);
4388 QueryProgramiv(programObject, pname, params);
4389}
4390
Jamie Madillbe849e42017-05-02 15:49:00 -04004391void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004392{
4393 Program *programObject = getProgram(program);
4394 ASSERT(programObject);
4395 programObject->getInfoLog(bufsize, length, infolog);
4396}
4397
4398void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4399{
4400 Shader *shaderObject = getShader(shader);
4401 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004402 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004403}
4404
4405void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4406{
4407 Shader *shaderObject = getShader(shader);
4408 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004409 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004410}
4411
4412void Context::getShaderPrecisionFormat(GLenum shadertype,
4413 GLenum precisiontype,
4414 GLint *range,
4415 GLint *precision)
4416{
4417 // TODO(jmadill): Compute shaders.
4418
4419 switch (shadertype)
4420 {
4421 case GL_VERTEX_SHADER:
4422 switch (precisiontype)
4423 {
4424 case GL_LOW_FLOAT:
4425 mCaps.vertexLowpFloat.get(range, precision);
4426 break;
4427 case GL_MEDIUM_FLOAT:
4428 mCaps.vertexMediumpFloat.get(range, precision);
4429 break;
4430 case GL_HIGH_FLOAT:
4431 mCaps.vertexHighpFloat.get(range, precision);
4432 break;
4433
4434 case GL_LOW_INT:
4435 mCaps.vertexLowpInt.get(range, precision);
4436 break;
4437 case GL_MEDIUM_INT:
4438 mCaps.vertexMediumpInt.get(range, precision);
4439 break;
4440 case GL_HIGH_INT:
4441 mCaps.vertexHighpInt.get(range, precision);
4442 break;
4443
4444 default:
4445 UNREACHABLE();
4446 return;
4447 }
4448 break;
4449
4450 case GL_FRAGMENT_SHADER:
4451 switch (precisiontype)
4452 {
4453 case GL_LOW_FLOAT:
4454 mCaps.fragmentLowpFloat.get(range, precision);
4455 break;
4456 case GL_MEDIUM_FLOAT:
4457 mCaps.fragmentMediumpFloat.get(range, precision);
4458 break;
4459 case GL_HIGH_FLOAT:
4460 mCaps.fragmentHighpFloat.get(range, precision);
4461 break;
4462
4463 case GL_LOW_INT:
4464 mCaps.fragmentLowpInt.get(range, precision);
4465 break;
4466 case GL_MEDIUM_INT:
4467 mCaps.fragmentMediumpInt.get(range, precision);
4468 break;
4469 case GL_HIGH_INT:
4470 mCaps.fragmentHighpInt.get(range, precision);
4471 break;
4472
4473 default:
4474 UNREACHABLE();
4475 return;
4476 }
4477 break;
4478
4479 default:
4480 UNREACHABLE();
4481 return;
4482 }
4483}
4484
4485void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4486{
4487 Shader *shaderObject = getShader(shader);
4488 ASSERT(shaderObject);
4489 shaderObject->getSource(bufsize, length, source);
4490}
4491
4492void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4493{
4494 Program *programObject = getProgram(program);
4495 ASSERT(programObject);
4496 programObject->getUniformfv(location, params);
4497}
4498
4499void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4500{
4501 Program *programObject = getProgram(program);
4502 ASSERT(programObject);
4503 programObject->getUniformiv(location, params);
4504}
4505
4506GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4507{
4508 Program *programObject = getProgram(program);
4509 ASSERT(programObject);
4510 return programObject->getUniformLocation(name);
4511}
4512
4513GLboolean Context::isBuffer(GLuint buffer)
4514{
4515 if (buffer == 0)
4516 {
4517 return GL_FALSE;
4518 }
4519
4520 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4521}
4522
4523GLboolean Context::isEnabled(GLenum cap)
4524{
4525 return mGLState.getEnableFeature(cap);
4526}
4527
4528GLboolean Context::isFramebuffer(GLuint framebuffer)
4529{
4530 if (framebuffer == 0)
4531 {
4532 return GL_FALSE;
4533 }
4534
4535 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4536}
4537
4538GLboolean Context::isProgram(GLuint program)
4539{
4540 if (program == 0)
4541 {
4542 return GL_FALSE;
4543 }
4544
4545 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4546}
4547
4548GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4549{
4550 if (renderbuffer == 0)
4551 {
4552 return GL_FALSE;
4553 }
4554
4555 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4556}
4557
4558GLboolean Context::isShader(GLuint shader)
4559{
4560 if (shader == 0)
4561 {
4562 return GL_FALSE;
4563 }
4564
4565 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4566}
4567
4568GLboolean Context::isTexture(GLuint texture)
4569{
4570 if (texture == 0)
4571 {
4572 return GL_FALSE;
4573 }
4574
4575 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4576}
4577
4578void Context::linkProgram(GLuint program)
4579{
4580 Program *programObject = getProgram(program);
4581 ASSERT(programObject);
4582 handleError(programObject->link(this));
4583}
4584
4585void Context::releaseShaderCompiler()
4586{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004587 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004588}
4589
4590void Context::shaderBinary(GLsizei n,
4591 const GLuint *shaders,
4592 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004593 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004594 GLsizei length)
4595{
4596 // No binary shader formats are supported.
4597 UNIMPLEMENTED();
4598}
4599
4600void Context::shaderSource(GLuint shader,
4601 GLsizei count,
4602 const GLchar *const *string,
4603 const GLint *length)
4604{
4605 Shader *shaderObject = getShader(shader);
4606 ASSERT(shaderObject);
4607 shaderObject->setSource(count, string, length);
4608}
4609
4610void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4611{
4612 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4613}
4614
4615void Context::stencilMask(GLuint mask)
4616{
4617 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4618}
4619
4620void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4621{
4622 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4623}
4624
4625void Context::uniform1f(GLint location, GLfloat x)
4626{
4627 Program *program = mGLState.getProgram();
4628 program->setUniform1fv(location, 1, &x);
4629}
4630
4631void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4632{
4633 Program *program = mGLState.getProgram();
4634 program->setUniform1fv(location, count, v);
4635}
4636
4637void Context::uniform1i(GLint location, GLint x)
4638{
4639 Program *program = mGLState.getProgram();
4640 program->setUniform1iv(location, 1, &x);
4641}
4642
4643void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4644{
4645 Program *program = mGLState.getProgram();
4646 program->setUniform1iv(location, count, v);
4647}
4648
4649void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4650{
4651 GLfloat xy[2] = {x, y};
4652 Program *program = mGLState.getProgram();
4653 program->setUniform2fv(location, 1, xy);
4654}
4655
4656void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4657{
4658 Program *program = mGLState.getProgram();
4659 program->setUniform2fv(location, count, v);
4660}
4661
4662void Context::uniform2i(GLint location, GLint x, GLint y)
4663{
4664 GLint xy[2] = {x, y};
4665 Program *program = mGLState.getProgram();
4666 program->setUniform2iv(location, 1, xy);
4667}
4668
4669void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4670{
4671 Program *program = mGLState.getProgram();
4672 program->setUniform2iv(location, count, v);
4673}
4674
4675void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4676{
4677 GLfloat xyz[3] = {x, y, z};
4678 Program *program = mGLState.getProgram();
4679 program->setUniform3fv(location, 1, xyz);
4680}
4681
4682void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4683{
4684 Program *program = mGLState.getProgram();
4685 program->setUniform3fv(location, count, v);
4686}
4687
4688void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4689{
4690 GLint xyz[3] = {x, y, z};
4691 Program *program = mGLState.getProgram();
4692 program->setUniform3iv(location, 1, xyz);
4693}
4694
4695void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4696{
4697 Program *program = mGLState.getProgram();
4698 program->setUniform3iv(location, count, v);
4699}
4700
4701void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4702{
4703 GLfloat xyzw[4] = {x, y, z, w};
4704 Program *program = mGLState.getProgram();
4705 program->setUniform4fv(location, 1, xyzw);
4706}
4707
4708void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4709{
4710 Program *program = mGLState.getProgram();
4711 program->setUniform4fv(location, count, v);
4712}
4713
4714void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4715{
4716 GLint xyzw[4] = {x, y, z, w};
4717 Program *program = mGLState.getProgram();
4718 program->setUniform4iv(location, 1, xyzw);
4719}
4720
4721void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4722{
4723 Program *program = mGLState.getProgram();
4724 program->setUniform4iv(location, count, v);
4725}
4726
4727void Context::uniformMatrix2fv(GLint location,
4728 GLsizei count,
4729 GLboolean transpose,
4730 const GLfloat *value)
4731{
4732 Program *program = mGLState.getProgram();
4733 program->setUniformMatrix2fv(location, count, transpose, value);
4734}
4735
4736void Context::uniformMatrix3fv(GLint location,
4737 GLsizei count,
4738 GLboolean transpose,
4739 const GLfloat *value)
4740{
4741 Program *program = mGLState.getProgram();
4742 program->setUniformMatrix3fv(location, count, transpose, value);
4743}
4744
4745void Context::uniformMatrix4fv(GLint location,
4746 GLsizei count,
4747 GLboolean transpose,
4748 const GLfloat *value)
4749{
4750 Program *program = mGLState.getProgram();
4751 program->setUniformMatrix4fv(location, count, transpose, value);
4752}
4753
4754void Context::validateProgram(GLuint program)
4755{
4756 Program *programObject = getProgram(program);
4757 ASSERT(programObject);
4758 programObject->validate(mCaps);
4759}
4760
Jamie Madilld04908b2017-06-09 14:15:35 -04004761void Context::getProgramBinary(GLuint program,
4762 GLsizei bufSize,
4763 GLsizei *length,
4764 GLenum *binaryFormat,
4765 void *binary)
4766{
4767 Program *programObject = getProgram(program);
4768 ASSERT(programObject != nullptr);
4769
4770 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4771}
4772
4773void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4774{
4775 Program *programObject = getProgram(program);
4776 ASSERT(programObject != nullptr);
4777
4778 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4779}
4780
Jamie Madillc29968b2016-01-20 11:17:23 -05004781} // namespace gl