blob: c6bc7997018c00a39a70eb7eff5e3c53fff57200 [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 Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
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 Madill9dd0cf02014-11-24 11:38:51 -050023#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"
37#include "libANGLE/formatutils.h"
38#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070039#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040040#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040041#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030042#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040043#include "libANGLE/queryutils.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>
Sami Väisänend59ca052016-06-21 16:10:00 +030049std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
50 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
69std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
70 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();
121 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
122 }
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 {
132 const OffsetBindingPointer<gl::Buffer> &buffer =
133 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
Martin Radev9d901792016-07-15 15:58:58 +0300202std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
203{
204 std::string labelName;
205 if (label != nullptr)
206 {
207 size_t labelLength = length < 0 ? strlen(label) : length;
208 labelName = std::string(label, labelLength);
209 }
210 return labelName;
211}
212
213void GetObjectLabelBase(const std::string &objectLabel,
214 GLsizei bufSize,
215 GLsizei *length,
216 GLchar *label)
217{
218 size_t writeLength = objectLabel.length();
219 if (label != nullptr && bufSize > 0)
220 {
221 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
222 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
223 label[writeLength] = '\0';
224 }
225
226 if (length != nullptr)
227 {
228 *length = static_cast<GLsizei>(writeLength);
229 }
230}
231
Geoff Langf6db0982015-08-25 13:04:00 -0400232} // anonymous namespace
233
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000234namespace gl
235{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000236
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400237Context::Context(rx::EGLImplFactory *implFactory,
238 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400239 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500240 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300241
Geoff Langeb66a6e2016-10-31 13:06:12 -0400242 : ValidationContext(GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700243 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500244 mCaps,
245 mTextureCaps,
246 mExtensions,
247 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500248 mLimitations,
Jamie Madill01a80ee2016-11-07 12:06:18 -0500249 mFramebufferMap,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500250 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700251 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500252 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400253 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500254 mClientType(EGL_OPENGL_ES_API),
255 mHasBeenCurrent(false),
256 mContextLost(false),
257 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700258 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500259 mResetStrategy(GetResetStrategy(attribs)),
260 mRobustAccess(GetRobustAccess(attribs)),
261 mCurrentSurface(nullptr),
262 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000263{
Geoff Lang077f20a2016-11-01 10:08:02 -0400264 if (mRobustAccess)
265 {
266 UNIMPLEMENTED();
267 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000268
Geoff Langc287ea62016-09-16 14:46:51 -0400269 initCaps(GetWebGLContext(attribs));
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700270 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400271
Geoff Langeb66a6e2016-10-31 13:06:12 -0400272 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400273 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100274
Shannon Woods53a94a82014-06-24 15:20:36 -0400275 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400276
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400277 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000278 {
279 mResourceManager = shareContext->mResourceManager;
280 mResourceManager->addRef();
281 }
282 else
283 {
Jamie Madill901b3792016-05-26 09:20:40 -0400284 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000285 }
286
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700287 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400288
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000289 // [OpenGL ES 2.0.24] section 3.7 page 83:
290 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
291 // and cube map texture state vectors respectively associated with them.
292 // In order that access to these initial textures not be lost, they are treated as texture
293 // objects all of whose names are 0.
294
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400295 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500296 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500297
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400298 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400300
Geoff Langeb66a6e2016-10-31 13:06:12 -0400301 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400302 {
303 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400304 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500305 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400306
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500308 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400309 }
Geoff Lang3b573612016-10-31 14:08:10 -0400310 if (getClientVersion() >= Version(3, 1))
311 {
312 Texture *zeroTexture2DMultisample =
313 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
314 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
315 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000316
Ian Ewellbda75592016-04-18 17:25:54 -0400317 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
318 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400319 Texture *zeroTextureExternal =
320 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400321 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
322 }
323
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700324 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500325
Jamie Madill57a89722013-07-02 11:57:03 -0400326 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000327 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800328 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000329 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400330
Jamie Madill01a80ee2016-11-07 12:06:18 -0500331 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000332
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000333 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500334 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000335 {
336 bindIndexedUniformBuffer(0, i, 0, -1);
337 }
338
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000339 bindCopyReadBuffer(0);
340 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000341 bindPixelPackBuffer(0);
342 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000343
Geoff Langeb66a6e2016-10-31 13:06:12 -0400344 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400345 {
346 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
347 // In the initial state, a default transform feedback object is bound and treated as
348 // a transform feedback object with a name of zero. That object is bound any time
349 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400350 bindTransformFeedback(0);
351 }
Geoff Langc8058452014-02-03 12:04:11 -0500352
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700353 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500354
355 // Initialize dirty bit masks
356 // TODO(jmadill): additional ES3 state
357 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
358 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
359 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
360 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
361 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
362 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400363 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500364 // No dirty objects.
365
366 // Readpixels uses the pack state and read FBO
367 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
368 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
369 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
370 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
371 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400372 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500373 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
374
375 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
376 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
377 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
378 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
379 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
380 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
381 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
382 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
383 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
384 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
385 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
386 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
387
388 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
389 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700390 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500391 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
392 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400393
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400394 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395}
396
397Context::~Context()
398{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700399 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000400
Corentin Wallez37c39792015-08-20 14:19:46 -0400401 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000402 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400403 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400404 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400405 {
406 SafeDelete(framebuffer.second);
407 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000408 }
409
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000411 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400412 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000413 }
414
Corentin Wallez80b24112015-08-25 16:41:57 -0400415 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000416 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400417 if (query.second != nullptr)
418 {
419 query.second->release();
420 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421 }
422
Corentin Wallez80b24112015-08-25 16:41:57 -0400423 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400424 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400425 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400426 }
427
Corentin Wallez80b24112015-08-25 16:41:57 -0400428 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500429 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500430 if (transformFeedback.second != nullptr)
431 {
432 transformFeedback.second->release();
433 }
Geoff Langc8058452014-02-03 12:04:11 -0500434 }
435
Jamie Madilldedd7b92014-11-05 16:30:36 -0500436 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400437 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500438 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400439 }
440 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000441
Corentin Wallez51706ea2015-08-07 14:39:22 -0400442 if (mCurrentSurface != nullptr)
443 {
444 releaseSurface();
445 }
446
Jamie Madill1e9ae072014-11-06 15:27:21 -0500447 if (mResourceManager)
448 {
449 mResourceManager->release();
450 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500451
452 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000453}
454
daniel@transgaming.comad629872012-11-28 19:32:06 +0000455void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000456{
Jamie Madill77a72f62015-04-14 11:18:32 -0400457 ASSERT(surface != nullptr);
458
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000459 if (!mHasBeenCurrent)
460 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000461 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500462 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400463 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000464
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700465 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
466 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000467
468 mHasBeenCurrent = true;
469 }
470
Jamie Madill1b94d432015-08-07 13:23:23 -0400471 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700472 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400473
Corentin Wallez51706ea2015-08-07 14:39:22 -0400474 if (mCurrentSurface)
475 {
476 releaseSurface();
477 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000478 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400479 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000480
Corentin Wallez37c39792015-08-20 14:19:46 -0400481 // Update default framebuffer, the binding of the previous default
482 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400483 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400484 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700485 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400486 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700487 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400488 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700489 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400490 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700491 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400492 }
493 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400494 }
Ian Ewell292f0052016-02-04 10:37:32 -0500495
496 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700497 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000498}
499
Jamie Madill77a72f62015-04-14 11:18:32 -0400500void Context::releaseSurface()
501{
Corentin Wallez37c39792015-08-20 14:19:46 -0400502 ASSERT(mCurrentSurface != nullptr);
503
504 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400505 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400506 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700507 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400508 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700509 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400510 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700511 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400512 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700513 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400514 }
515 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400516 }
517
Corentin Wallez51706ea2015-08-07 14:39:22 -0400518 mCurrentSurface->setIsCurrent(false);
519 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400520}
521
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000522GLuint Context::createBuffer()
523{
524 return mResourceManager->createBuffer();
525}
526
527GLuint Context::createProgram()
528{
Jamie Madill901b3792016-05-26 09:20:40 -0400529 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000530}
531
532GLuint Context::createShader(GLenum type)
533{
Jamie Madill901b3792016-05-26 09:20:40 -0400534 return mResourceManager->createShader(mImplementation.get(),
535 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000536}
537
538GLuint Context::createTexture()
539{
540 return mResourceManager->createTexture();
541}
542
543GLuint Context::createRenderbuffer()
544{
545 return mResourceManager->createRenderbuffer();
546}
547
Geoff Lang882033e2014-09-30 11:26:07 -0400548GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400549{
Jamie Madill901b3792016-05-26 09:20:40 -0400550 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400551
Cooper Partind8e62a32015-01-29 15:21:25 -0800552 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400553}
554
Sami Väisänene45e53b2016-05-25 10:36:04 +0300555GLuint Context::createPaths(GLsizei range)
556{
557 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
558 if (resultOrError.isError())
559 {
560 handleError(resultOrError.getError());
561 return 0;
562 }
563 return resultOrError.getResult();
564}
565
Jamie Madill57a89722013-07-02 11:57:03 -0400566GLuint Context::createVertexArray()
567{
Geoff Lang36167ab2015-12-07 10:27:14 -0500568 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
569 mVertexArrayMap[vertexArray] = nullptr;
570 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400571}
572
Jamie Madilldc356042013-07-19 16:36:57 -0400573GLuint Context::createSampler()
574{
575 return mResourceManager->createSampler();
576}
577
Geoff Langc8058452014-02-03 12:04:11 -0500578GLuint Context::createTransformFeedback()
579{
Geoff Lang36167ab2015-12-07 10:27:14 -0500580 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
581 mTransformFeedbackMap[transformFeedback] = nullptr;
582 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500583}
584
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585// Returns an unused framebuffer name
586GLuint Context::createFramebuffer()
587{
588 GLuint handle = mFramebufferHandleAllocator.allocate();
589
590 mFramebufferMap[handle] = NULL;
591
592 return handle;
593}
594
Jamie Madill33dc8432013-07-26 11:55:05 -0400595GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000596{
Jamie Madill33dc8432013-07-26 11:55:05 -0400597 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000598
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400599 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000600
601 return handle;
602}
603
604// Returns an unused query name
605GLuint Context::createQuery()
606{
607 GLuint handle = mQueryHandleAllocator.allocate();
608
609 mQueryMap[handle] = NULL;
610
611 return handle;
612}
613
614void Context::deleteBuffer(GLuint buffer)
615{
616 if (mResourceManager->getBuffer(buffer))
617 {
618 detachBuffer(buffer);
619 }
Jamie Madill893ab082014-05-16 16:56:10 -0400620
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000621 mResourceManager->deleteBuffer(buffer);
622}
623
624void Context::deleteShader(GLuint shader)
625{
626 mResourceManager->deleteShader(shader);
627}
628
629void Context::deleteProgram(GLuint program)
630{
631 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000632}
633
634void Context::deleteTexture(GLuint texture)
635{
636 if (mResourceManager->getTexture(texture))
637 {
638 detachTexture(texture);
639 }
640
641 mResourceManager->deleteTexture(texture);
642}
643
644void Context::deleteRenderbuffer(GLuint renderbuffer)
645{
646 if (mResourceManager->getRenderbuffer(renderbuffer))
647 {
648 detachRenderbuffer(renderbuffer);
649 }
Jamie Madill893ab082014-05-16 16:56:10 -0400650
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651 mResourceManager->deleteRenderbuffer(renderbuffer);
652}
653
Jamie Madillcd055f82013-07-26 11:55:15 -0400654void Context::deleteFenceSync(GLsync fenceSync)
655{
656 // The spec specifies the underlying Fence object is not deleted until all current
657 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
658 // and since our API is currently designed for being called from a single thread, we can delete
659 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700660 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400661}
662
Sami Väisänene45e53b2016-05-25 10:36:04 +0300663void Context::deletePaths(GLuint first, GLsizei range)
664{
665 mResourceManager->deletePaths(first, range);
666}
667
668bool Context::hasPathData(GLuint path) const
669{
670 const auto *pathObj = mResourceManager->getPath(path);
671 if (pathObj == nullptr)
672 return false;
673
674 return pathObj->hasPathData();
675}
676
677bool Context::hasPath(GLuint path) const
678{
679 return mResourceManager->hasPath(path);
680}
681
682void Context::setPathCommands(GLuint path,
683 GLsizei numCommands,
684 const GLubyte *commands,
685 GLsizei numCoords,
686 GLenum coordType,
687 const void *coords)
688{
689 auto *pathObject = mResourceManager->getPath(path);
690
691 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
692}
693
694void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
695{
696 auto *pathObj = mResourceManager->getPath(path);
697
698 switch (pname)
699 {
700 case GL_PATH_STROKE_WIDTH_CHROMIUM:
701 pathObj->setStrokeWidth(value);
702 break;
703 case GL_PATH_END_CAPS_CHROMIUM:
704 pathObj->setEndCaps(static_cast<GLenum>(value));
705 break;
706 case GL_PATH_JOIN_STYLE_CHROMIUM:
707 pathObj->setJoinStyle(static_cast<GLenum>(value));
708 break;
709 case GL_PATH_MITER_LIMIT_CHROMIUM:
710 pathObj->setMiterLimit(value);
711 break;
712 case GL_PATH_STROKE_BOUND_CHROMIUM:
713 pathObj->setStrokeBound(value);
714 break;
715 default:
716 UNREACHABLE();
717 break;
718 }
719}
720
721void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
722{
723 const auto *pathObj = mResourceManager->getPath(path);
724
725 switch (pname)
726 {
727 case GL_PATH_STROKE_WIDTH_CHROMIUM:
728 *value = pathObj->getStrokeWidth();
729 break;
730 case GL_PATH_END_CAPS_CHROMIUM:
731 *value = static_cast<GLfloat>(pathObj->getEndCaps());
732 break;
733 case GL_PATH_JOIN_STYLE_CHROMIUM:
734 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
735 break;
736 case GL_PATH_MITER_LIMIT_CHROMIUM:
737 *value = pathObj->getMiterLimit();
738 break;
739 case GL_PATH_STROKE_BOUND_CHROMIUM:
740 *value = pathObj->getStrokeBound();
741 break;
742 default:
743 UNREACHABLE();
744 break;
745 }
746}
747
748void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
749{
750 mGLState.setPathStencilFunc(func, ref, mask);
751}
752
Jamie Madill57a89722013-07-02 11:57:03 -0400753void Context::deleteVertexArray(GLuint vertexArray)
754{
Geoff Lang36167ab2015-12-07 10:27:14 -0500755 auto iter = mVertexArrayMap.find(vertexArray);
756 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000757 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500758 VertexArray *vertexArrayObject = iter->second;
759 if (vertexArrayObject != nullptr)
760 {
761 detachVertexArray(vertexArray);
762 delete vertexArrayObject;
763 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000764
Geoff Lang36167ab2015-12-07 10:27:14 -0500765 mVertexArrayMap.erase(iter);
766 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400767 }
768}
769
Jamie Madilldc356042013-07-19 16:36:57 -0400770void Context::deleteSampler(GLuint sampler)
771{
772 if (mResourceManager->getSampler(sampler))
773 {
774 detachSampler(sampler);
775 }
776
777 mResourceManager->deleteSampler(sampler);
778}
779
Geoff Langc8058452014-02-03 12:04:11 -0500780void Context::deleteTransformFeedback(GLuint transformFeedback)
781{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500782 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500783 if (iter != mTransformFeedbackMap.end())
784 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500785 TransformFeedback *transformFeedbackObject = iter->second;
786 if (transformFeedbackObject != nullptr)
787 {
788 detachTransformFeedback(transformFeedback);
789 transformFeedbackObject->release();
790 }
791
Geoff Lang50b3fe82015-12-08 14:49:12 +0000792 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500793 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500794 }
795}
796
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000797void Context::deleteFramebuffer(GLuint framebuffer)
798{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500799 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800
801 if (framebufferObject != mFramebufferMap.end())
802 {
803 detachFramebuffer(framebuffer);
804
805 mFramebufferHandleAllocator.release(framebufferObject->first);
806 delete framebufferObject->second;
807 mFramebufferMap.erase(framebufferObject);
808 }
809}
810
Jamie Madill33dc8432013-07-26 11:55:05 -0400811void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000812{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500813 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000814
Jamie Madill33dc8432013-07-26 11:55:05 -0400815 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400817 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000818 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400819 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820 }
821}
822
823void Context::deleteQuery(GLuint query)
824{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500825 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000826 if (queryObject != mQueryMap.end())
827 {
828 mQueryHandleAllocator.release(queryObject->first);
829 if (queryObject->second)
830 {
831 queryObject->second->release();
832 }
833 mQueryMap.erase(queryObject);
834 }
835}
836
Geoff Lang70d0f492015-12-10 17:45:46 -0500837Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000838{
839 return mResourceManager->getBuffer(handle);
840}
841
Jamie Madill570f7c82014-07-03 10:38:54 -0400842Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843{
844 return mResourceManager->getTexture(handle);
845}
846
Geoff Lang70d0f492015-12-10 17:45:46 -0500847Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000848{
849 return mResourceManager->getRenderbuffer(handle);
850}
851
Jamie Madillcd055f82013-07-26 11:55:15 -0400852FenceSync *Context::getFenceSync(GLsync handle) const
853{
Minmin Gong794e0002015-04-07 18:31:54 -0700854 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400855}
856
Jamie Madill57a89722013-07-02 11:57:03 -0400857VertexArray *Context::getVertexArray(GLuint handle) const
858{
859 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500860 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400861}
862
Jamie Madilldc356042013-07-19 16:36:57 -0400863Sampler *Context::getSampler(GLuint handle) const
864{
865 return mResourceManager->getSampler(handle);
866}
867
Geoff Langc8058452014-02-03 12:04:11 -0500868TransformFeedback *Context::getTransformFeedback(GLuint handle) const
869{
Geoff Lang36167ab2015-12-07 10:27:14 -0500870 auto iter = mTransformFeedbackMap.find(handle);
871 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500872}
873
Geoff Lang70d0f492015-12-10 17:45:46 -0500874LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
875{
876 switch (identifier)
877 {
878 case GL_BUFFER:
879 return getBuffer(name);
880 case GL_SHADER:
881 return getShader(name);
882 case GL_PROGRAM:
883 return getProgram(name);
884 case GL_VERTEX_ARRAY:
885 return getVertexArray(name);
886 case GL_QUERY:
887 return getQuery(name);
888 case GL_TRANSFORM_FEEDBACK:
889 return getTransformFeedback(name);
890 case GL_SAMPLER:
891 return getSampler(name);
892 case GL_TEXTURE:
893 return getTexture(name);
894 case GL_RENDERBUFFER:
895 return getRenderbuffer(name);
896 case GL_FRAMEBUFFER:
897 return getFramebuffer(name);
898 default:
899 UNREACHABLE();
900 return nullptr;
901 }
902}
903
904LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
905{
906 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
907}
908
Martin Radev9d901792016-07-15 15:58:58 +0300909void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
910{
911 LabeledObject *object = getLabeledObject(identifier, name);
912 ASSERT(object != nullptr);
913
914 std::string labelName = GetObjectLabelFromPointer(length, label);
915 object->setLabel(labelName);
916}
917
918void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
919{
920 LabeledObject *object = getLabeledObjectFromPtr(ptr);
921 ASSERT(object != nullptr);
922
923 std::string labelName = GetObjectLabelFromPointer(length, label);
924 object->setLabel(labelName);
925}
926
927void Context::getObjectLabel(GLenum identifier,
928 GLuint name,
929 GLsizei bufSize,
930 GLsizei *length,
931 GLchar *label) const
932{
933 LabeledObject *object = getLabeledObject(identifier, name);
934 ASSERT(object != nullptr);
935
936 const std::string &objectLabel = object->getLabel();
937 GetObjectLabelBase(objectLabel, bufSize, length, label);
938}
939
940void Context::getObjectPtrLabel(const void *ptr,
941 GLsizei bufSize,
942 GLsizei *length,
943 GLchar *label) const
944{
945 LabeledObject *object = getLabeledObjectFromPtr(ptr);
946 ASSERT(object != nullptr);
947
948 const std::string &objectLabel = object->getLabel();
949 GetObjectLabelBase(objectLabel, bufSize, length, label);
950}
951
Jamie Madilldc356042013-07-19 16:36:57 -0400952bool Context::isSampler(GLuint samplerName) const
953{
954 return mResourceManager->isSampler(samplerName);
955}
956
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500957void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958{
Jamie Madill901b3792016-05-26 09:20:40 -0400959 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700960 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000961}
962
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800963void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
964{
965 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
966 mGLState.setDrawIndirectBufferBinding(buffer);
967}
968
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500969void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000970{
Jamie Madill901b3792016-05-26 09:20:40 -0400971 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700972 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000973}
974
Jamie Madilldedd7b92014-11-05 16:30:36 -0500975void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500977 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978
Jamie Madilldedd7b92014-11-05 16:30:36 -0500979 if (handle == 0)
980 {
981 texture = mZeroTextures[target].get();
982 }
983 else
984 {
Jamie Madill901b3792016-05-26 09:20:40 -0400985 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500986 }
987
988 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700989 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000990}
991
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500992void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500994 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700995 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996}
997
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500998void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001000 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001001 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001002}
1003
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001004void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001005{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001006 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001007 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001008}
1009
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001010void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001011{
Geoff Lang76b10c92014-09-05 16:28:14 -04001012 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001013 Sampler *sampler =
1014 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001015 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001016}
1017
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001018void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001019{
Jamie Madill901b3792016-05-26 09:20:40 -04001020 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001022}
1023
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1025 GLuint index,
1026 GLintptr offset,
1027 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001028{
Jamie Madill901b3792016-05-26 09:20:40 -04001029 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001030 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001031}
1032
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001033void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001034{
Jamie Madill901b3792016-05-26 09:20:40 -04001035 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001036 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001037}
1038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1040 GLuint index,
1041 GLintptr offset,
1042 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001043{
Jamie Madill901b3792016-05-26 09:20:40 -04001044 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001045 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001046}
1047
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001048void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001049{
Jamie Madill901b3792016-05-26 09:20:40 -04001050 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001051 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001052}
1053
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001054void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001055{
Jamie Madill901b3792016-05-26 09:20:40 -04001056 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001057 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001061{
Jamie Madill901b3792016-05-26 09:20:40 -04001062 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001067{
Jamie Madill901b3792016-05-26 09:20:40 -04001068 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001069 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001070}
1071
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001072void Context::useProgram(GLuint program)
1073{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001074 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001075}
1076
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001077void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001078{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001079 TransformFeedback *transformFeedback =
1080 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001081 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001082}
1083
Geoff Lang5aad9672014-09-08 11:10:42 -04001084Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001086 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001087 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088
Geoff Lang5aad9672014-09-08 11:10:42 -04001089 // begin query
1090 Error error = queryObject->begin();
1091 if (error.isError())
1092 {
1093 return error;
1094 }
1095
1096 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001097 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001098
Geoff Lang5aad9672014-09-08 11:10:42 -04001099 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001100}
1101
Geoff Lang5aad9672014-09-08 11:10:42 -04001102Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001103{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001104 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001105 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106
Geoff Lang5aad9672014-09-08 11:10:42 -04001107 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001108
Geoff Lang5aad9672014-09-08 11:10:42 -04001109 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001110 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001111
1112 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001113}
1114
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001115Error Context::queryCounter(GLuint id, GLenum target)
1116{
1117 ASSERT(target == GL_TIMESTAMP_EXT);
1118
1119 Query *queryObject = getQuery(id, true, target);
1120 ASSERT(queryObject);
1121
1122 return queryObject->queryCounter();
1123}
1124
1125void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1126{
1127 switch (pname)
1128 {
1129 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001130 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001131 break;
1132 case GL_QUERY_COUNTER_BITS_EXT:
1133 switch (target)
1134 {
1135 case GL_TIME_ELAPSED_EXT:
1136 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1137 break;
1138 case GL_TIMESTAMP_EXT:
1139 params[0] = getExtensions().queryCounterBitsTimestamp;
1140 break;
1141 default:
1142 UNREACHABLE();
1143 params[0] = 0;
1144 break;
1145 }
1146 break;
1147 default:
1148 UNREACHABLE();
1149 return;
1150 }
1151}
1152
Geoff Lang2186c382016-10-14 10:54:54 -04001153void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001154{
Geoff Lang2186c382016-10-14 10:54:54 -04001155 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001156}
1157
Geoff Lang2186c382016-10-14 10:54:54 -04001158void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001159{
Geoff Lang2186c382016-10-14 10:54:54 -04001160 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001161}
1162
Geoff Lang2186c382016-10-14 10:54:54 -04001163void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001164{
Geoff Lang2186c382016-10-14 10:54:54 -04001165 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001166}
1167
Geoff Lang2186c382016-10-14 10:54:54 -04001168void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001169{
Geoff Lang2186c382016-10-14 10:54:54 -04001170 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001171}
1172
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001173Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001175 auto framebufferIt = mFramebufferMap.find(handle);
1176 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177}
1178
Jamie Madill33dc8432013-07-26 11:55:05 -04001179FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001181 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001182
Jamie Madill33dc8432013-07-26 11:55:05 -04001183 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184 {
1185 return NULL;
1186 }
1187 else
1188 {
1189 return fence->second;
1190 }
1191}
1192
1193Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1194{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001195 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001196
1197 if (query == mQueryMap.end())
1198 {
1199 return NULL;
1200 }
1201 else
1202 {
1203 if (!query->second && create)
1204 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001205 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206 query->second->addRef();
1207 }
1208 return query->second;
1209 }
1210}
1211
Geoff Lang70d0f492015-12-10 17:45:46 -05001212Query *Context::getQuery(GLuint handle) const
1213{
1214 auto iter = mQueryMap.find(handle);
1215 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1216}
1217
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001218Texture *Context::getTargetTexture(GLenum target) const
1219{
Ian Ewellbda75592016-04-18 17:25:54 -04001220 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001221 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001222}
1223
Geoff Lang76b10c92014-09-05 16:28:14 -04001224Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001226 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001227}
1228
Geoff Lang492a7e42014-11-05 13:27:06 -05001229Compiler *Context::getCompiler() const
1230{
1231 return mCompiler;
1232}
1233
Jamie Madill893ab082014-05-16 16:56:10 -04001234void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235{
1236 switch (pname)
1237 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001238 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001239 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001241 mGLState.getBooleanv(pname, params);
1242 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244}
1245
Jamie Madill893ab082014-05-16 16:56:10 -04001246void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001247{
Shannon Woods53a94a82014-06-24 15:20:36 -04001248 // Queries about context capabilities and maximums are answered by Context.
1249 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250 switch (pname)
1251 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001252 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001253 params[0] = mCaps.minAliasedLineWidth;
1254 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255 break;
1256 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001257 params[0] = mCaps.minAliasedPointSize;
1258 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001259 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001260 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001261 ASSERT(mExtensions.textureFilterAnisotropic);
1262 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001263 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001264 case GL_MAX_TEXTURE_LOD_BIAS:
1265 *params = mCaps.maxLODBias;
1266 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001267
1268 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1269 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1270 {
1271 ASSERT(mExtensions.pathRendering);
1272 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1273 memcpy(params, m, 16 * sizeof(GLfloat));
1274 }
1275 break;
1276
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001278 mGLState.getFloatv(pname, params);
1279 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281}
1282
Jamie Madill893ab082014-05-16 16:56:10 -04001283void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284{
Shannon Woods53a94a82014-06-24 15:20:36 -04001285 // Queries about context capabilities and maximums are answered by Context.
1286 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001287
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001288 switch (pname)
1289 {
Geoff Lang301d1612014-07-09 10:34:37 -04001290 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1291 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1292 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001293 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1294 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1295 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001296 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1297 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1298 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001299 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001300 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1301 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1302 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001303 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001304 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001305 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1306 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1307 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1308 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001309 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1310 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001311 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1312 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001313 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001314 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1315 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1316 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1317 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001318 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001319 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001320 break;
1321 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001322 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001323 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001324 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1325 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001326 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1327 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1328 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001329 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1330 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1331 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001332 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001333 case GL_MAX_VIEWPORT_DIMS:
1334 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001335 params[0] = mCaps.maxViewportWidth;
1336 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001337 }
1338 break;
1339 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001340 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001341 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001342 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1343 *params = mResetStrategy;
1344 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001345 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001346 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001347 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001348 case GL_SHADER_BINARY_FORMATS:
1349 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1350 break;
1351 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001352 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001353 break;
1354 case GL_PROGRAM_BINARY_FORMATS:
1355 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001356 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001357 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001358 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001359 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001360
1361 // GL_KHR_debug
1362 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1363 *params = mExtensions.maxDebugMessageLength;
1364 break;
1365 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1366 *params = mExtensions.maxDebugLoggedMessages;
1367 break;
1368 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1369 *params = mExtensions.maxDebugGroupStackDepth;
1370 break;
1371 case GL_MAX_LABEL_LENGTH:
1372 *params = mExtensions.maxLabelLength;
1373 break;
1374
Ian Ewell53f59f42016-01-28 17:36:55 -05001375 // GL_EXT_disjoint_timer_query
1376 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001377 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001378 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001379 case GL_MAX_FRAMEBUFFER_WIDTH:
1380 *params = mCaps.maxFramebufferWidth;
1381 break;
1382 case GL_MAX_FRAMEBUFFER_HEIGHT:
1383 *params = mCaps.maxFramebufferHeight;
1384 break;
1385 case GL_MAX_FRAMEBUFFER_SAMPLES:
1386 *params = mCaps.maxFramebufferSamples;
1387 break;
1388 case GL_MAX_SAMPLE_MASK_WORDS:
1389 *params = mCaps.maxSampleMaskWords;
1390 break;
1391 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1392 *params = mCaps.maxColorTextureSamples;
1393 break;
1394 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1395 *params = mCaps.maxDepthTextureSamples;
1396 break;
1397 case GL_MAX_INTEGER_SAMPLES:
1398 *params = mCaps.maxIntegerSamples;
1399 break;
1400 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1401 *params = mCaps.maxVertexAttribRelativeOffset;
1402 break;
1403 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1404 *params = mCaps.maxVertexAttribBindings;
1405 break;
1406 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1407 *params = mCaps.maxVertexAttribStride;
1408 break;
1409 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1410 *params = mCaps.maxVertexAtomicCounterBuffers;
1411 break;
1412 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1413 *params = mCaps.maxVertexAtomicCounters;
1414 break;
1415 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1416 *params = mCaps.maxVertexImageUniforms;
1417 break;
1418 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1419 *params = mCaps.maxVertexShaderStorageBlocks;
1420 break;
1421 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1422 *params = mCaps.maxFragmentAtomicCounterBuffers;
1423 break;
1424 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1425 *params = mCaps.maxFragmentAtomicCounters;
1426 break;
1427 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1428 *params = mCaps.maxFragmentImageUniforms;
1429 break;
1430 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1431 *params = mCaps.maxFragmentShaderStorageBlocks;
1432 break;
1433 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1434 *params = mCaps.minProgramTextureGatherOffset;
1435 break;
1436 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1437 *params = mCaps.maxProgramTextureGatherOffset;
1438 break;
1439 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1440 *params = mCaps.maxComputeWorkGroupInvocations;
1441 break;
1442 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1443 *params = mCaps.maxComputeUniformBlocks;
1444 break;
1445 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1446 *params = mCaps.maxComputeTextureImageUnits;
1447 break;
1448 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1449 *params = mCaps.maxComputeSharedMemorySize;
1450 break;
1451 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1452 *params = mCaps.maxComputeUniformComponents;
1453 break;
1454 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1455 *params = mCaps.maxComputeAtomicCounterBuffers;
1456 break;
1457 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1458 *params = mCaps.maxComputeAtomicCounters;
1459 break;
1460 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1461 *params = mCaps.maxComputeImageUniforms;
1462 break;
1463 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1464 *params = mCaps.maxCombinedComputeUniformComponents;
1465 break;
1466 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1467 *params = mCaps.maxComputeShaderStorageBlocks;
1468 break;
1469 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1470 *params = mCaps.maxCombinedShaderOutputResources;
1471 break;
1472 case GL_MAX_UNIFORM_LOCATIONS:
1473 *params = mCaps.maxUniformLocations;
1474 break;
1475 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1476 *params = mCaps.maxAtomicCounterBufferBindings;
1477 break;
1478 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1479 *params = mCaps.maxAtomicCounterBufferSize;
1480 break;
1481 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1482 *params = mCaps.maxCombinedAtomicCounterBuffers;
1483 break;
1484 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1485 *params = mCaps.maxCombinedAtomicCounters;
1486 break;
1487 case GL_MAX_IMAGE_UNITS:
1488 *params = mCaps.maxImageUnits;
1489 break;
1490 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1491 *params = mCaps.maxCombinedImageUniforms;
1492 break;
1493 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1494 *params = mCaps.maxShaderStorageBufferBindings;
1495 break;
1496 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1497 *params = mCaps.maxCombinedShaderStorageBlocks;
1498 break;
1499 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1500 *params = mCaps.shaderStorageBufferOffsetAlignment;
1501 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001502 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001503 mGLState.getIntegerv(mState, pname, params);
1504 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001505 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001506}
1507
Jamie Madill893ab082014-05-16 16:56:10 -04001508void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001509{
Shannon Woods53a94a82014-06-24 15:20:36 -04001510 // Queries about context capabilities and maximums are answered by Context.
1511 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001512 switch (pname)
1513 {
1514 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001515 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001516 break;
1517 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001518 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001519 break;
1520 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001521 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001522 break;
1523 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001524 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001525 break;
1526 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001527 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001528 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001529
1530 // GL_EXT_disjoint_timer_query
1531 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001532 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001533 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001534
1535 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1536 *params = mCaps.maxShaderStorageBlockSize;
1537 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001538 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001539 UNREACHABLE();
1540 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001541 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001542}
1543
Geoff Lang70d0f492015-12-10 17:45:46 -05001544void Context::getPointerv(GLenum pname, void **params) const
1545{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001546 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001547}
1548
Martin Radev66fb8202016-07-28 11:45:20 +03001549void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001550{
Shannon Woods53a94a82014-06-24 15:20:36 -04001551 // Queries about context capabilities and maximums are answered by Context.
1552 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001553
1554 GLenum nativeType;
1555 unsigned int numParams;
1556 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1557 ASSERT(queryStatus);
1558
1559 if (nativeType == GL_INT)
1560 {
1561 switch (target)
1562 {
1563 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1564 ASSERT(index < 3u);
1565 *data = mCaps.maxComputeWorkGroupCount[index];
1566 break;
1567 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1568 ASSERT(index < 3u);
1569 *data = mCaps.maxComputeWorkGroupSize[index];
1570 break;
1571 default:
1572 mGLState.getIntegeri_v(target, index, data);
1573 }
1574 }
1575 else
1576 {
1577 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1578 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001579}
1580
Martin Radev66fb8202016-07-28 11:45:20 +03001581void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001582{
Shannon Woods53a94a82014-06-24 15:20:36 -04001583 // Queries about context capabilities and maximums are answered by Context.
1584 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001585
1586 GLenum nativeType;
1587 unsigned int numParams;
1588 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1589 ASSERT(queryStatus);
1590
1591 if (nativeType == GL_INT_64_ANGLEX)
1592 {
1593 mGLState.getInteger64i_v(target, index, data);
1594 }
1595 else
1596 {
1597 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1598 }
1599}
1600
1601void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1602{
1603 // Queries about context capabilities and maximums are answered by Context.
1604 // Queries about current GL state values are answered by State.
1605
1606 GLenum nativeType;
1607 unsigned int numParams;
1608 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1609 ASSERT(queryStatus);
1610
1611 if (nativeType == GL_BOOL)
1612 {
1613 mGLState.getBooleani_v(target, index, data);
1614 }
1615 else
1616 {
1617 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1618 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001619}
1620
Geoff Langf6db0982015-08-25 13:04:00 -04001621Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001622{
Jamie Madill1b94d432015-08-07 13:23:23 -04001623 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001624 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001625 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001626
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001627 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001628}
1629
Geoff Langf6db0982015-08-25 13:04:00 -04001630Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1631{
1632 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001633 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001634 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001635
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001636 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001637}
1638
1639Error Context::drawElements(GLenum mode,
1640 GLsizei count,
1641 GLenum type,
1642 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001643 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001644{
Jamie Madill1b94d432015-08-07 13:23:23 -04001645 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001646 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001647}
1648
1649Error Context::drawElementsInstanced(GLenum mode,
1650 GLsizei count,
1651 GLenum type,
1652 const GLvoid *indices,
1653 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001654 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001655{
1656 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001657 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1658 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001659}
1660
1661Error Context::drawRangeElements(GLenum mode,
1662 GLuint start,
1663 GLuint end,
1664 GLsizei count,
1665 GLenum type,
1666 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001667 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001668{
1669 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001670 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001671}
1672
Jiajia Qind9671222016-11-29 16:30:31 +08001673void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1674{
1675 syncRendererState();
1676 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1677}
1678
1679void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1680{
1681 syncRendererState();
1682 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1683}
1684
Geoff Lang129753a2015-01-09 16:52:09 -05001685Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001686{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001687 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001688}
1689
1690Error Context::finish()
1691{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001692 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001693}
1694
Austin Kinross6ee1e782015-05-29 17:05:37 -07001695void Context::insertEventMarker(GLsizei length, const char *marker)
1696{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001697 ASSERT(mImplementation);
1698 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001699}
1700
1701void Context::pushGroupMarker(GLsizei length, const char *marker)
1702{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001703 ASSERT(mImplementation);
1704 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001705}
1706
1707void Context::popGroupMarker()
1708{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001709 ASSERT(mImplementation);
1710 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001711}
1712
Geoff Langd8605522016-04-13 10:19:12 -04001713void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1714{
1715 Program *programObject = getProgram(program);
1716 ASSERT(programObject);
1717
1718 programObject->bindUniformLocation(location, name);
1719}
1720
Sami Väisänena797e062016-05-12 15:23:40 +03001721void Context::setCoverageModulation(GLenum components)
1722{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001723 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001724}
1725
Sami Väisänene45e53b2016-05-25 10:36:04 +03001726void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1727{
1728 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1729}
1730
1731void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1732{
1733 GLfloat I[16];
1734 angle::Matrix<GLfloat>::setToIdentity(I);
1735
1736 mGLState.loadPathRenderingMatrix(matrixMode, I);
1737}
1738
1739void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1740{
1741 const auto *pathObj = mResourceManager->getPath(path);
1742 if (!pathObj)
1743 return;
1744
1745 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1746 syncRendererState();
1747
1748 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1749}
1750
1751void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1752{
1753 const auto *pathObj = mResourceManager->getPath(path);
1754 if (!pathObj)
1755 return;
1756
1757 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1758 syncRendererState();
1759
1760 mImplementation->stencilStrokePath(pathObj, reference, mask);
1761}
1762
1763void Context::coverFillPath(GLuint path, GLenum coverMode)
1764{
1765 const auto *pathObj = mResourceManager->getPath(path);
1766 if (!pathObj)
1767 return;
1768
1769 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1770 syncRendererState();
1771
1772 mImplementation->coverFillPath(pathObj, coverMode);
1773}
1774
1775void Context::coverStrokePath(GLuint path, GLenum coverMode)
1776{
1777 const auto *pathObj = mResourceManager->getPath(path);
1778 if (!pathObj)
1779 return;
1780
1781 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1782 syncRendererState();
1783
1784 mImplementation->coverStrokePath(pathObj, coverMode);
1785}
1786
1787void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1788{
1789 const auto *pathObj = mResourceManager->getPath(path);
1790 if (!pathObj)
1791 return;
1792
1793 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1794 syncRendererState();
1795
1796 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1797}
1798
1799void Context::stencilThenCoverStrokePath(GLuint path,
1800 GLint reference,
1801 GLuint mask,
1802 GLenum coverMode)
1803{
1804 const auto *pathObj = mResourceManager->getPath(path);
1805 if (!pathObj)
1806 return;
1807
1808 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1809 syncRendererState();
1810
1811 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1812}
1813
Sami Väisänend59ca052016-06-21 16:10:00 +03001814void Context::coverFillPathInstanced(GLsizei numPaths,
1815 GLenum pathNameType,
1816 const void *paths,
1817 GLuint pathBase,
1818 GLenum coverMode,
1819 GLenum transformType,
1820 const GLfloat *transformValues)
1821{
1822 const auto &pathObjects =
1823 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1824
1825 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1826 syncRendererState();
1827
1828 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1829}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001830
Sami Väisänend59ca052016-06-21 16:10:00 +03001831void Context::coverStrokePathInstanced(GLsizei numPaths,
1832 GLenum pathNameType,
1833 const void *paths,
1834 GLuint pathBase,
1835 GLenum coverMode,
1836 GLenum transformType,
1837 const GLfloat *transformValues)
1838{
1839 const auto &pathObjects =
1840 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1841
1842 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1843 syncRendererState();
1844
1845 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1846 transformValues);
1847}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001848
Sami Väisänend59ca052016-06-21 16:10:00 +03001849void Context::stencilFillPathInstanced(GLsizei numPaths,
1850 GLenum pathNameType,
1851 const void *paths,
1852 GLuint pathBase,
1853 GLenum fillMode,
1854 GLuint mask,
1855 GLenum transformType,
1856 const GLfloat *transformValues)
1857{
1858 const auto &pathObjects =
1859 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1860
1861 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1862 syncRendererState();
1863
1864 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1865 transformValues);
1866}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001867
Sami Väisänend59ca052016-06-21 16:10:00 +03001868void Context::stencilStrokePathInstanced(GLsizei numPaths,
1869 GLenum pathNameType,
1870 const void *paths,
1871 GLuint pathBase,
1872 GLint reference,
1873 GLuint mask,
1874 GLenum transformType,
1875 const GLfloat *transformValues)
1876{
1877 const auto &pathObjects =
1878 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1879
1880 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1881 syncRendererState();
1882
1883 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1884 transformValues);
1885}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001886
Sami Väisänend59ca052016-06-21 16:10:00 +03001887void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1888 GLenum pathNameType,
1889 const void *paths,
1890 GLuint pathBase,
1891 GLenum fillMode,
1892 GLuint mask,
1893 GLenum coverMode,
1894 GLenum transformType,
1895 const GLfloat *transformValues)
1896{
1897 const auto &pathObjects =
1898 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1899
1900 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1901 syncRendererState();
1902
1903 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1904 transformType, transformValues);
1905}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001906
Sami Väisänend59ca052016-06-21 16:10:00 +03001907void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1908 GLenum pathNameType,
1909 const void *paths,
1910 GLuint pathBase,
1911 GLint reference,
1912 GLuint mask,
1913 GLenum coverMode,
1914 GLenum transformType,
1915 const GLfloat *transformValues)
1916{
1917 const auto &pathObjects =
1918 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1919
1920 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1921 syncRendererState();
1922
1923 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1924 transformType, transformValues);
1925}
1926
Sami Väisänen46eaa942016-06-29 10:26:37 +03001927void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1928{
1929 auto *programObject = getProgram(program);
1930
1931 programObject->bindFragmentInputLocation(location, name);
1932}
1933
1934void Context::programPathFragmentInputGen(GLuint program,
1935 GLint location,
1936 GLenum genMode,
1937 GLint components,
1938 const GLfloat *coeffs)
1939{
1940 auto *programObject = getProgram(program);
1941
1942 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1943}
1944
Jamie Madill437fa652016-05-03 15:13:24 -04001945void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001946{
Geoff Langda5777c2014-07-11 09:52:58 -04001947 if (error.isError())
1948 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001949 GLenum code = error.getCode();
1950 mErrors.insert(code);
1951 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1952 {
1953 markContextLost();
1954 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001955
1956 if (!error.getMessage().empty())
1957 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001958 auto *debug = &mGLState.getDebug();
1959 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1960 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001961 }
Geoff Langda5777c2014-07-11 09:52:58 -04001962 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001963}
1964
1965// Get one of the recorded errors and clear its flag, if any.
1966// [OpenGL ES 2.0.24] section 2.5 page 13.
1967GLenum Context::getError()
1968{
Geoff Langda5777c2014-07-11 09:52:58 -04001969 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001970 {
Geoff Langda5777c2014-07-11 09:52:58 -04001971 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001972 }
Geoff Langda5777c2014-07-11 09:52:58 -04001973 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001974 {
Geoff Langda5777c2014-07-11 09:52:58 -04001975 GLenum error = *mErrors.begin();
1976 mErrors.erase(mErrors.begin());
1977 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001978 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001979}
1980
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001981// NOTE: this function should not assume that this context is current!
1982void Context::markContextLost()
1983{
1984 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001985 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001986 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001987 mContextLostForced = true;
1988 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001989 mContextLost = true;
1990}
1991
1992bool Context::isContextLost()
1993{
1994 return mContextLost;
1995}
1996
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001997GLenum Context::getResetStatus()
1998{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001999 // Even if the application doesn't want to know about resets, we want to know
2000 // as it will allow us to skip all the calls.
2001 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002002 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002003 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002004 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002005 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002006 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002007
2008 // EXT_robustness, section 2.6: If the reset notification behavior is
2009 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2010 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2011 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002012 }
2013
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002014 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2015 // status should be returned at least once, and GL_NO_ERROR should be returned
2016 // once the device has finished resetting.
2017 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002018 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002019 ASSERT(mResetStatus == GL_NO_ERROR);
2020 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002021
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002022 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002023 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002024 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002025 }
2026 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002027 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002028 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002029 // If markContextLost was used to mark the context lost then
2030 // assume that is not recoverable, and continue to report the
2031 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002032 mResetStatus = mImplementation->getResetStatus();
2033 }
Jamie Madill893ab082014-05-16 16:56:10 -04002034
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002035 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002036}
2037
2038bool Context::isResetNotificationEnabled()
2039{
2040 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2041}
2042
Corentin Walleze3b10e82015-05-20 11:06:25 -04002043const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002044{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002045 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002046}
2047
2048EGLenum Context::getClientType() const
2049{
2050 return mClientType;
2051}
2052
2053EGLenum Context::getRenderBuffer() const
2054{
Corentin Wallez37c39792015-08-20 14:19:46 -04002055 auto framebufferIt = mFramebufferMap.find(0);
2056 if (framebufferIt != mFramebufferMap.end())
2057 {
2058 const Framebuffer *framebuffer = framebufferIt->second;
2059 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2060
2061 ASSERT(backAttachment != nullptr);
2062 return backAttachment->getSurface()->getRenderBuffer();
2063 }
2064 else
2065 {
2066 return EGL_NONE;
2067 }
Régis Fénéon83107972015-02-05 12:57:44 +01002068}
2069
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002070VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002071{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002072 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002073 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2074 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002075 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002076 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2077
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002078 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002079 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002080
2081 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002082}
2083
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002084TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002085{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002086 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002087 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2088 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002089 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002090 transformFeedback =
2091 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002092 transformFeedback->addRef();
2093 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002094 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002095
2096 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002097}
2098
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002099Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2100{
2101 // Can be called from Bind without a prior call to Gen.
2102 auto framebufferIt = mFramebufferMap.find(framebuffer);
2103 bool neverCreated = framebufferIt == mFramebufferMap.end();
2104 if (neverCreated || framebufferIt->second == nullptr)
2105 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002106 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002107 if (neverCreated)
2108 {
2109 mFramebufferHandleAllocator.reserve(framebuffer);
2110 mFramebufferMap[framebuffer] = newFBO;
2111 return newFBO;
2112 }
2113
2114 framebufferIt->second = newFBO;
2115 }
2116
2117 return framebufferIt->second;
2118}
2119
Geoff Lang36167ab2015-12-07 10:27:14 -05002120bool Context::isVertexArrayGenerated(GLuint vertexArray)
2121{
Geoff Langf41a7152016-09-19 15:11:17 -04002122 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002123 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2124}
2125
2126bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2127{
Geoff Langf41a7152016-09-19 15:11:17 -04002128 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002129 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2130}
2131
Shannon Woods53a94a82014-06-24 15:20:36 -04002132void Context::detachTexture(GLuint texture)
2133{
2134 // Simple pass-through to State's detachTexture method, as textures do not require
2135 // allocation map management either here or in the resource manager at detach time.
2136 // Zero textures are held by the Context, and we don't attempt to request them from
2137 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002138 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002139}
2140
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002141void Context::detachBuffer(GLuint buffer)
2142{
Yuly Novikov5807a532015-12-03 13:01:22 -05002143 // Simple pass-through to State's detachBuffer method, since
2144 // only buffer attachments to container objects that are bound to the current context
2145 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002146
Yuly Novikov5807a532015-12-03 13:01:22 -05002147 // [OpenGL ES 3.2] section 5.1.2 page 45:
2148 // Attachments to unbound container objects, such as
2149 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2150 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002151 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002152}
2153
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002154void Context::detachFramebuffer(GLuint framebuffer)
2155{
Shannon Woods53a94a82014-06-24 15:20:36 -04002156 // Framebuffer detachment is handled by Context, because 0 is a valid
2157 // Framebuffer object, and a pointer to it must be passed from Context
2158 // to State at binding time.
2159
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002160 // [OpenGL ES 2.0.24] section 4.4 page 107:
2161 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2162 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2163
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002164 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002165 {
2166 bindReadFramebuffer(0);
2167 }
2168
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002169 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002170 {
2171 bindDrawFramebuffer(0);
2172 }
2173}
2174
2175void Context::detachRenderbuffer(GLuint renderbuffer)
2176{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002177 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002178}
2179
Jamie Madill57a89722013-07-02 11:57:03 -04002180void Context::detachVertexArray(GLuint vertexArray)
2181{
Jamie Madill77a72f62015-04-14 11:18:32 -04002182 // Vertex array detachment is handled by Context, because 0 is a valid
2183 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002184 // binding time.
2185
Jamie Madill57a89722013-07-02 11:57:03 -04002186 // [OpenGL ES 3.0.2] section 2.10 page 43:
2187 // If a vertex array object that is currently bound is deleted, the binding
2188 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002189 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002190 {
2191 bindVertexArray(0);
2192 }
2193}
2194
Geoff Langc8058452014-02-03 12:04:11 -05002195void Context::detachTransformFeedback(GLuint transformFeedback)
2196{
Corentin Walleza2257da2016-04-19 16:43:12 -04002197 // Transform feedback detachment is handled by Context, because 0 is a valid
2198 // transform feedback, and a pointer to it must be passed from Context to State at
2199 // binding time.
2200
2201 // The OpenGL specification doesn't mention what should happen when the currently bound
2202 // transform feedback object is deleted. Since it is a container object, we treat it like
2203 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002204 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002205 {
2206 bindTransformFeedback(0);
2207 }
Geoff Langc8058452014-02-03 12:04:11 -05002208}
2209
Jamie Madilldc356042013-07-19 16:36:57 -04002210void Context::detachSampler(GLuint sampler)
2211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002212 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002213}
2214
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002215void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002217 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002218}
2219
Jamie Madille29d1672013-07-19 16:36:57 -04002220void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2221{
Geoff Langc1984ed2016-10-07 12:41:00 -04002222 Sampler *samplerObject =
2223 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2224 SetSamplerParameteri(samplerObject, pname, param);
2225}
Jamie Madille29d1672013-07-19 16:36:57 -04002226
Geoff Langc1984ed2016-10-07 12:41:00 -04002227void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2228{
2229 Sampler *samplerObject =
2230 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2231 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002232}
2233
2234void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2235{
Geoff Langc1984ed2016-10-07 12:41:00 -04002236 Sampler *samplerObject =
2237 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2238 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002239}
2240
Geoff Langc1984ed2016-10-07 12:41:00 -04002241void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002242{
Geoff Langc1984ed2016-10-07 12:41:00 -04002243 Sampler *samplerObject =
2244 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2245 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002246}
2247
Geoff Langc1984ed2016-10-07 12:41:00 -04002248void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002249{
Geoff Langc1984ed2016-10-07 12:41:00 -04002250 const Sampler *samplerObject =
2251 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2252 QuerySamplerParameteriv(samplerObject, pname, params);
2253}
Jamie Madill9675b802013-07-19 16:36:59 -04002254
Geoff Langc1984ed2016-10-07 12:41:00 -04002255void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2256{
2257 const Sampler *samplerObject =
2258 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2259 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002260}
2261
Olli Etuahof0fee072016-03-30 15:11:58 +03002262void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2263{
2264 gl::Program *programObject = getProgram(program);
2265 ASSERT(programObject != nullptr);
2266
2267 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2268 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2269}
2270
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002271void Context::initRendererString()
2272{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002273 std::ostringstream rendererString;
2274 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002275 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002276 rendererString << ")";
2277
Geoff Langcec35902014-04-16 10:52:36 -04002278 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002279}
2280
Geoff Langc339c4e2016-11-29 10:37:36 -05002281void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002282{
Geoff Langc339c4e2016-11-29 10:37:36 -05002283 const Version &clientVersion = getClientVersion();
2284
2285 std::ostringstream versionString;
2286 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2287 << ANGLE_VERSION_STRING << ")";
2288 mVersionString = MakeStaticString(versionString.str());
2289
2290 std::ostringstream shadingLanguageVersionString;
2291 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2292 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2293 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2294 << ")";
2295 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002296}
2297
Geoff Langcec35902014-04-16 10:52:36 -04002298void Context::initExtensionStrings()
2299{
Geoff Langc339c4e2016-11-29 10:37:36 -05002300 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2301 std::ostringstream combinedStringStream;
2302 std::copy(strings.begin(), strings.end(),
2303 std::ostream_iterator<const char *>(combinedStringStream, " "));
2304 return MakeStaticString(combinedStringStream.str());
2305 };
2306
2307 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002308 for (const auto &extensionString : mExtensions.getStrings())
2309 {
2310 mExtensionStrings.push_back(MakeStaticString(extensionString));
2311 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002312 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002313
Geoff Langc339c4e2016-11-29 10:37:36 -05002314 mRequestableExtensionStrings.clear();
2315 for (const auto &extensionInfo : GetExtensionInfoMap())
2316 {
2317 if (extensionInfo.second.Requestable &&
2318 !(mExtensions.*(extensionInfo.second.ExtensionsMember)))
2319 {
2320 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2321 }
2322 }
2323 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002324}
2325
Geoff Langc339c4e2016-11-29 10:37:36 -05002326const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002327{
Geoff Langc339c4e2016-11-29 10:37:36 -05002328 switch (name)
2329 {
2330 case GL_VENDOR:
2331 return reinterpret_cast<const GLubyte *>("Google Inc.");
2332
2333 case GL_RENDERER:
2334 return reinterpret_cast<const GLubyte *>(mRendererString);
2335
2336 case GL_VERSION:
2337 return reinterpret_cast<const GLubyte *>(mVersionString);
2338
2339 case GL_SHADING_LANGUAGE_VERSION:
2340 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2341
2342 case GL_EXTENSIONS:
2343 return reinterpret_cast<const GLubyte *>(mExtensionString);
2344
2345 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2346 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2347
2348 default:
2349 UNREACHABLE();
2350 return nullptr;
2351 }
Geoff Langcec35902014-04-16 10:52:36 -04002352}
2353
Geoff Langc339c4e2016-11-29 10:37:36 -05002354const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002355{
Geoff Langc339c4e2016-11-29 10:37:36 -05002356 switch (name)
2357 {
2358 case GL_EXTENSIONS:
2359 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2360
2361 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2362 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2363
2364 default:
2365 UNREACHABLE();
2366 return nullptr;
2367 }
Geoff Langcec35902014-04-16 10:52:36 -04002368}
2369
2370size_t Context::getExtensionStringCount() const
2371{
2372 return mExtensionStrings.size();
2373}
2374
Geoff Langc339c4e2016-11-29 10:37:36 -05002375void Context::requestExtension(const char *name)
2376{
2377 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2378 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2379 const auto &extension = extensionInfos.at(name);
2380 ASSERT(extension.Requestable);
2381
2382 if (mExtensions.*(extension.ExtensionsMember))
2383 {
2384 // Extension already enabled
2385 return;
2386 }
2387
2388 mExtensions.*(extension.ExtensionsMember) = true;
2389 updateCaps();
2390 initExtensionStrings();
2391}
2392
2393size_t Context::getRequestableExtensionStringCount() const
2394{
2395 return mRequestableExtensionStrings.size();
2396}
2397
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002398void Context::beginTransformFeedback(GLenum primitiveMode)
2399{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002400 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002401 ASSERT(transformFeedback != nullptr);
2402 ASSERT(!transformFeedback->isPaused());
2403
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002404 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002405}
2406
2407bool Context::hasActiveTransformFeedback(GLuint program) const
2408{
2409 for (auto pair : mTransformFeedbackMap)
2410 {
2411 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2412 {
2413 return true;
2414 }
2415 }
2416 return false;
2417}
2418
Geoff Langc287ea62016-09-16 14:46:51 -04002419void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002420{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002421 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002422
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002423 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002424
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002425 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002426
Geoff Langeb66a6e2016-10-31 13:06:12 -04002427 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002428 {
2429 // Disable ES3+ extensions
2430 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002431 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002432 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002433 }
2434
Geoff Langeb66a6e2016-10-31 13:06:12 -04002435 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002436 {
2437 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2438 //mExtensions.sRGB = false;
2439 }
2440
Jamie Madill00ed7a12016-05-19 13:13:38 -04002441 // Some extensions are always available because they are implemented in the GL layer.
2442 mExtensions.bindUniformLocation = true;
2443 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002444 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002445 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002446
2447 // Enable the no error extension if the context was created with the flag.
2448 mExtensions.noError = mSkipValidation;
2449
Geoff Lang70d0f492015-12-10 17:45:46 -05002450 // Explicitly enable GL_KHR_debug
2451 mExtensions.debug = true;
2452 mExtensions.maxDebugMessageLength = 1024;
2453 mExtensions.maxDebugLoggedMessages = 1024;
2454 mExtensions.maxDebugGroupStackDepth = 1024;
2455 mExtensions.maxLabelLength = 1024;
2456
Geoff Langff5b2d52016-09-07 11:32:23 -04002457 // Explicitly enable GL_ANGLE_robust_client_memory
2458 mExtensions.robustClientMemory = true;
2459
Geoff Lang301d1612014-07-09 10:34:37 -04002460 // Apply implementation limits
2461 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002462 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2463 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2464
2465 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002466
Geoff Langc287ea62016-09-16 14:46:51 -04002467 // WebGL compatibility
2468 mExtensions.webglCompatibility = webGLContext;
2469 for (const auto &extensionInfo : GetExtensionInfoMap())
2470 {
2471 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002472 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002473 {
2474 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2475 }
2476 }
2477
2478 // Generate texture caps
2479 updateCaps();
2480}
2481
2482void Context::updateCaps()
2483{
Geoff Lang900013c2014-07-07 11:32:19 -04002484 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002485 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002486
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002487 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002488 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2489 {
2490 GLenum format = i->first;
2491 TextureCaps formatCaps = i->second;
2492
Geoff Lang5d601382014-07-22 15:14:06 -04002493 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002494
Geoff Lang0d8b7242015-09-09 14:56:53 -04002495 // Update the format caps based on the client version and extensions.
2496 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2497 // ES3.
2498 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002499 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002500 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002501 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002502 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002503 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002504
2505 // OpenGL ES does not support multisampling with integer formats
2506 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002507 {
Geoff Langd87878e2014-09-19 15:42:59 -04002508 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002509 }
Geoff Langd87878e2014-09-19 15:42:59 -04002510
2511 if (formatCaps.texturable && formatInfo.compressed)
2512 {
2513 mCaps.compressedTextureFormats.push_back(format);
2514 }
2515
2516 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002517 }
2518}
2519
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002520void Context::initWorkarounds()
2521{
2522 // Lose the context upon out of memory error if the application is
2523 // expecting to watch for those events.
2524 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2525}
2526
Jamie Madill1b94d432015-08-07 13:23:23 -04002527void Context::syncRendererState()
2528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002529 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2530 mImplementation->syncState(mGLState, dirtyBits);
2531 mGLState.clearDirtyBits();
2532 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002533}
2534
Jamie Madillad9f24e2016-02-12 09:27:24 -05002535void Context::syncRendererState(const State::DirtyBits &bitMask,
2536 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002537{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002538 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2539 mImplementation->syncState(mGLState, dirtyBits);
2540 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002541
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002542 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002543}
Jamie Madillc29968b2016-01-20 11:17:23 -05002544
2545void Context::blitFramebuffer(GLint srcX0,
2546 GLint srcY0,
2547 GLint srcX1,
2548 GLint srcY1,
2549 GLint dstX0,
2550 GLint dstY0,
2551 GLint dstX1,
2552 GLint dstY1,
2553 GLbitfield mask,
2554 GLenum filter)
2555{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002556 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002557 ASSERT(drawFramebuffer);
2558
2559 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2560 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2561
Jamie Madillad9f24e2016-02-12 09:27:24 -05002562 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002563
Jamie Madill8415b5f2016-04-26 13:41:39 -04002564 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002565}
Jamie Madillc29968b2016-01-20 11:17:23 -05002566
2567void Context::clear(GLbitfield mask)
2568{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002569 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002570 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002571}
2572
2573void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2574{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002575 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002576 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2577 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002578}
2579
2580void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2581{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002582 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002583 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2584 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002585}
2586
2587void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2588{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002589 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002590 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2591 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002592}
2593
2594void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2595{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002596 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002597 ASSERT(framebufferObject);
2598
2599 // If a buffer is not present, the clear has no effect
2600 if (framebufferObject->getDepthbuffer() == nullptr &&
2601 framebufferObject->getStencilbuffer() == nullptr)
2602 {
2603 return;
2604 }
2605
Jamie Madillad9f24e2016-02-12 09:27:24 -05002606 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002607 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2608 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002609}
2610
2611void Context::readPixels(GLint x,
2612 GLint y,
2613 GLsizei width,
2614 GLsizei height,
2615 GLenum format,
2616 GLenum type,
2617 GLvoid *pixels)
2618{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002619 if (width == 0 || height == 0)
2620 {
2621 return;
2622 }
2623
Jamie Madillad9f24e2016-02-12 09:27:24 -05002624 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002625
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002626 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002627 ASSERT(framebufferObject);
2628
2629 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002630 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002631}
2632
2633void Context::copyTexImage2D(GLenum target,
2634 GLint level,
2635 GLenum internalformat,
2636 GLint x,
2637 GLint y,
2638 GLsizei width,
2639 GLsizei height,
2640 GLint border)
2641{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002642 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002643 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002644
Jamie Madillc29968b2016-01-20 11:17:23 -05002645 Rectangle sourceArea(x, y, width, height);
2646
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002647 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002648 Texture *texture =
2649 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002650 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002651}
2652
2653void Context::copyTexSubImage2D(GLenum target,
2654 GLint level,
2655 GLint xoffset,
2656 GLint yoffset,
2657 GLint x,
2658 GLint y,
2659 GLsizei width,
2660 GLsizei height)
2661{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002662 if (width == 0 || height == 0)
2663 {
2664 return;
2665 }
2666
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002667 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002668 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002669
Jamie Madillc29968b2016-01-20 11:17:23 -05002670 Offset destOffset(xoffset, yoffset, 0);
2671 Rectangle sourceArea(x, y, width, height);
2672
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002673 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002674 Texture *texture =
2675 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002676 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002677}
2678
2679void Context::copyTexSubImage3D(GLenum target,
2680 GLint level,
2681 GLint xoffset,
2682 GLint yoffset,
2683 GLint zoffset,
2684 GLint x,
2685 GLint y,
2686 GLsizei width,
2687 GLsizei height)
2688{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002689 if (width == 0 || height == 0)
2690 {
2691 return;
2692 }
2693
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002694 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002695 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002696
Jamie Madillc29968b2016-01-20 11:17:23 -05002697 Offset destOffset(xoffset, yoffset, zoffset);
2698 Rectangle sourceArea(x, y, width, height);
2699
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002700 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002701 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002702 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002703}
2704
2705void Context::framebufferTexture2D(GLenum target,
2706 GLenum attachment,
2707 GLenum textarget,
2708 GLuint texture,
2709 GLint level)
2710{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002711 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002712 ASSERT(framebuffer);
2713
2714 if (texture != 0)
2715 {
2716 Texture *textureObj = getTexture(texture);
2717
2718 ImageIndex index = ImageIndex::MakeInvalid();
2719
2720 if (textarget == GL_TEXTURE_2D)
2721 {
2722 index = ImageIndex::Make2D(level);
2723 }
2724 else
2725 {
2726 ASSERT(IsCubeMapTextureTarget(textarget));
2727 index = ImageIndex::MakeCube(textarget, level);
2728 }
2729
2730 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2731 }
2732 else
2733 {
2734 framebuffer->resetAttachment(attachment);
2735 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002736
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002737 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002738}
2739
2740void Context::framebufferRenderbuffer(GLenum target,
2741 GLenum attachment,
2742 GLenum renderbuffertarget,
2743 GLuint renderbuffer)
2744{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002745 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002746 ASSERT(framebuffer);
2747
2748 if (renderbuffer != 0)
2749 {
2750 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2751 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2752 renderbufferObject);
2753 }
2754 else
2755 {
2756 framebuffer->resetAttachment(attachment);
2757 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002758
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002759 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002760}
2761
2762void Context::framebufferTextureLayer(GLenum target,
2763 GLenum attachment,
2764 GLuint texture,
2765 GLint level,
2766 GLint layer)
2767{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002768 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002769 ASSERT(framebuffer);
2770
2771 if (texture != 0)
2772 {
2773 Texture *textureObject = getTexture(texture);
2774
2775 ImageIndex index = ImageIndex::MakeInvalid();
2776
2777 if (textureObject->getTarget() == GL_TEXTURE_3D)
2778 {
2779 index = ImageIndex::Make3D(level, layer);
2780 }
2781 else
2782 {
2783 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2784 index = ImageIndex::Make2DArray(level, layer);
2785 }
2786
2787 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2788 }
2789 else
2790 {
2791 framebuffer->resetAttachment(attachment);
2792 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002793
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002794 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002795}
2796
2797void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2798{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002799 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002800 ASSERT(framebuffer);
2801 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002802 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002803}
2804
2805void Context::readBuffer(GLenum mode)
2806{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002807 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002808 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002809 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002810}
2811
2812void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2813{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002814 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002815 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002816
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002817 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002818 ASSERT(framebuffer);
2819
2820 // The specification isn't clear what should be done when the framebuffer isn't complete.
2821 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002822 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002823}
2824
2825void Context::invalidateFramebuffer(GLenum target,
2826 GLsizei numAttachments,
2827 const GLenum *attachments)
2828{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002829 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002830 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002831
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002832 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002833 ASSERT(framebuffer);
2834
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002835 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002836 {
Jamie Madill437fa652016-05-03 15:13:24 -04002837 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002838 }
Jamie Madill437fa652016-05-03 15:13:24 -04002839
2840 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002841}
2842
2843void Context::invalidateSubFramebuffer(GLenum target,
2844 GLsizei numAttachments,
2845 const GLenum *attachments,
2846 GLint x,
2847 GLint y,
2848 GLsizei width,
2849 GLsizei height)
2850{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002851 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002852 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002853
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002854 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002855 ASSERT(framebuffer);
2856
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002857 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002858 {
Jamie Madill437fa652016-05-03 15:13:24 -04002859 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002860 }
Jamie Madill437fa652016-05-03 15:13:24 -04002861
2862 Rectangle area(x, y, width, height);
2863 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002864}
2865
Jamie Madill73a84962016-02-12 09:27:23 -05002866void Context::texImage2D(GLenum target,
2867 GLint level,
2868 GLint internalformat,
2869 GLsizei width,
2870 GLsizei height,
2871 GLint border,
2872 GLenum format,
2873 GLenum type,
2874 const GLvoid *pixels)
2875{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002876 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002877
2878 Extents size(width, height, 1);
2879 Texture *texture =
2880 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002881 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002882 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002883}
2884
2885void Context::texImage3D(GLenum target,
2886 GLint level,
2887 GLint internalformat,
2888 GLsizei width,
2889 GLsizei height,
2890 GLsizei depth,
2891 GLint border,
2892 GLenum format,
2893 GLenum type,
2894 const GLvoid *pixels)
2895{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002896 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002897
2898 Extents size(width, height, depth);
2899 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002900 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002901 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002902}
2903
2904void Context::texSubImage2D(GLenum target,
2905 GLint level,
2906 GLint xoffset,
2907 GLint yoffset,
2908 GLsizei width,
2909 GLsizei height,
2910 GLenum format,
2911 GLenum type,
2912 const GLvoid *pixels)
2913{
2914 // Zero sized uploads are valid but no-ops
2915 if (width == 0 || height == 0)
2916 {
2917 return;
2918 }
2919
Jamie Madillad9f24e2016-02-12 09:27:24 -05002920 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002921
2922 Box area(xoffset, yoffset, 0, width, height, 1);
2923 Texture *texture =
2924 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002925 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002926 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002927}
2928
2929void Context::texSubImage3D(GLenum target,
2930 GLint level,
2931 GLint xoffset,
2932 GLint yoffset,
2933 GLint zoffset,
2934 GLsizei width,
2935 GLsizei height,
2936 GLsizei depth,
2937 GLenum format,
2938 GLenum type,
2939 const GLvoid *pixels)
2940{
2941 // Zero sized uploads are valid but no-ops
2942 if (width == 0 || height == 0 || depth == 0)
2943 {
2944 return;
2945 }
2946
Jamie Madillad9f24e2016-02-12 09:27:24 -05002947 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002948
2949 Box area(xoffset, yoffset, zoffset, width, height, depth);
2950 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002951 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002952 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002953}
2954
2955void Context::compressedTexImage2D(GLenum target,
2956 GLint level,
2957 GLenum internalformat,
2958 GLsizei width,
2959 GLsizei height,
2960 GLint border,
2961 GLsizei imageSize,
2962 const GLvoid *data)
2963{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002964 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002965
2966 Extents size(width, height, 1);
2967 Texture *texture =
2968 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002969 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2970 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002971 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002972}
2973
2974void Context::compressedTexImage3D(GLenum target,
2975 GLint level,
2976 GLenum internalformat,
2977 GLsizei width,
2978 GLsizei height,
2979 GLsizei depth,
2980 GLint border,
2981 GLsizei imageSize,
2982 const GLvoid *data)
2983{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002984 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002985
2986 Extents size(width, height, depth);
2987 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002988 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2989 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002990 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002991}
2992
2993void Context::compressedTexSubImage2D(GLenum target,
2994 GLint level,
2995 GLint xoffset,
2996 GLint yoffset,
2997 GLsizei width,
2998 GLsizei height,
2999 GLenum format,
3000 GLsizei imageSize,
3001 const GLvoid *data)
3002{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003003 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003004
3005 Box area(xoffset, yoffset, 0, width, height, 1);
3006 Texture *texture =
3007 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003008 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3009 format, imageSize,
3010 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003011}
3012
3013void Context::compressedTexSubImage3D(GLenum target,
3014 GLint level,
3015 GLint xoffset,
3016 GLint yoffset,
3017 GLint zoffset,
3018 GLsizei width,
3019 GLsizei height,
3020 GLsizei depth,
3021 GLenum format,
3022 GLsizei imageSize,
3023 const GLvoid *data)
3024{
3025 // Zero sized uploads are valid but no-ops
3026 if (width == 0 || height == 0)
3027 {
3028 return;
3029 }
3030
Jamie Madillad9f24e2016-02-12 09:27:24 -05003031 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003032
3033 Box area(xoffset, yoffset, zoffset, width, height, depth);
3034 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003035 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3036 format, imageSize,
3037 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003038}
3039
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003040void Context::generateMipmap(GLenum target)
3041{
3042 Texture *texture = getTargetTexture(target);
3043 handleError(texture->generateMipmap());
3044}
3045
Geoff Lang97073d12016-04-20 10:42:34 -07003046void Context::copyTextureCHROMIUM(GLuint sourceId,
3047 GLuint destId,
3048 GLint internalFormat,
3049 GLenum destType,
3050 GLboolean unpackFlipY,
3051 GLboolean unpackPremultiplyAlpha,
3052 GLboolean unpackUnmultiplyAlpha)
3053{
3054 syncStateForTexImage();
3055
3056 gl::Texture *sourceTexture = getTexture(sourceId);
3057 gl::Texture *destTexture = getTexture(destId);
3058 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3059 unpackPremultiplyAlpha == GL_TRUE,
3060 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3061}
3062
3063void Context::copySubTextureCHROMIUM(GLuint sourceId,
3064 GLuint destId,
3065 GLint xoffset,
3066 GLint yoffset,
3067 GLint x,
3068 GLint y,
3069 GLsizei width,
3070 GLsizei height,
3071 GLboolean unpackFlipY,
3072 GLboolean unpackPremultiplyAlpha,
3073 GLboolean unpackUnmultiplyAlpha)
3074{
3075 // Zero sized copies are valid but no-ops
3076 if (width == 0 || height == 0)
3077 {
3078 return;
3079 }
3080
3081 syncStateForTexImage();
3082
3083 gl::Texture *sourceTexture = getTexture(sourceId);
3084 gl::Texture *destTexture = getTexture(destId);
3085 Offset offset(xoffset, yoffset, 0);
3086 Rectangle area(x, y, width, height);
3087 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3088 unpackPremultiplyAlpha == GL_TRUE,
3089 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3090}
3091
Geoff Lang47110bf2016-04-20 11:13:22 -07003092void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3093{
3094 syncStateForTexImage();
3095
3096 gl::Texture *sourceTexture = getTexture(sourceId);
3097 gl::Texture *destTexture = getTexture(destId);
3098 handleError(destTexture->copyCompressedTexture(sourceTexture));
3099}
3100
Geoff Lang496c02d2016-10-20 11:38:11 -07003101void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003102{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003103 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003104 ASSERT(buffer);
3105
Geoff Lang496c02d2016-10-20 11:38:11 -07003106 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003107}
3108
3109GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3110{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003111 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003112 ASSERT(buffer);
3113
3114 Error error = buffer->map(access);
3115 if (error.isError())
3116 {
Jamie Madill437fa652016-05-03 15:13:24 -04003117 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003118 return nullptr;
3119 }
3120
3121 return buffer->getMapPointer();
3122}
3123
3124GLboolean Context::unmapBuffer(GLenum target)
3125{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003126 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003127 ASSERT(buffer);
3128
3129 GLboolean result;
3130 Error error = buffer->unmap(&result);
3131 if (error.isError())
3132 {
Jamie Madill437fa652016-05-03 15:13:24 -04003133 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003134 return GL_FALSE;
3135 }
3136
3137 return result;
3138}
3139
3140GLvoid *Context::mapBufferRange(GLenum target,
3141 GLintptr offset,
3142 GLsizeiptr length,
3143 GLbitfield access)
3144{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003145 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003146 ASSERT(buffer);
3147
3148 Error error = buffer->mapRange(offset, length, access);
3149 if (error.isError())
3150 {
Jamie Madill437fa652016-05-03 15:13:24 -04003151 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003152 return nullptr;
3153 }
3154
3155 return buffer->getMapPointer();
3156}
3157
3158void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3159{
3160 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3161}
3162
Jamie Madillad9f24e2016-02-12 09:27:24 -05003163void Context::syncStateForReadPixels()
3164{
3165 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3166}
3167
3168void Context::syncStateForTexImage()
3169{
3170 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3171}
3172
3173void Context::syncStateForClear()
3174{
3175 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3176}
3177
3178void Context::syncStateForBlit()
3179{
3180 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3181}
3182
Jamie Madillc20ab272016-06-09 07:20:46 -07003183void Context::activeTexture(GLenum texture)
3184{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003185 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003186}
3187
3188void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3189{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003190 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003191}
3192
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003193void Context::blendEquation(GLenum mode)
3194{
3195 mGLState.setBlendEquation(mode, mode);
3196}
3197
Jamie Madillc20ab272016-06-09 07:20:46 -07003198void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3199{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003200 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003201}
3202
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003203void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3204{
3205 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3206}
3207
Jamie Madillc20ab272016-06-09 07:20:46 -07003208void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3209{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003210 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003211}
3212
3213void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3214{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003215 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003216}
3217
3218void Context::clearDepthf(GLclampf depth)
3219{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003220 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003221}
3222
3223void Context::clearStencil(GLint s)
3224{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003225 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003226}
3227
3228void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3229{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003230 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003231}
3232
3233void Context::cullFace(GLenum mode)
3234{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003235 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003236}
3237
3238void Context::depthFunc(GLenum func)
3239{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003240 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003241}
3242
3243void Context::depthMask(GLboolean flag)
3244{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003245 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003246}
3247
3248void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3249{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003250 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003251}
3252
3253void Context::disable(GLenum cap)
3254{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003255 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003256}
3257
3258void Context::disableVertexAttribArray(GLuint index)
3259{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003260 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003261}
3262
3263void Context::enable(GLenum cap)
3264{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003265 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003266}
3267
3268void Context::enableVertexAttribArray(GLuint index)
3269{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003270 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003271}
3272
3273void Context::frontFace(GLenum mode)
3274{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003275 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003276}
3277
3278void Context::hint(GLenum target, GLenum mode)
3279{
3280 switch (target)
3281 {
3282 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003283 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003284 break;
3285
3286 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003287 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003288 break;
3289
3290 default:
3291 UNREACHABLE();
3292 return;
3293 }
3294}
3295
3296void Context::lineWidth(GLfloat width)
3297{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003298 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003299}
3300
3301void Context::pixelStorei(GLenum pname, GLint param)
3302{
3303 switch (pname)
3304 {
3305 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003306 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003307 break;
3308
3309 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003310 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003311 break;
3312
3313 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003314 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003315 break;
3316
3317 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003318 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003319 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003320 break;
3321
3322 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003323 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003324 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003325 break;
3326
3327 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003328 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003329 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003330 break;
3331
3332 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003333 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335 break;
3336
3337 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003338 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340 break;
3341
3342 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003343 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345 break;
3346
3347 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003348 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003350 break;
3351
3352 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003353 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003355 break;
3356
3357 default:
3358 UNREACHABLE();
3359 return;
3360 }
3361}
3362
3363void Context::polygonOffset(GLfloat factor, GLfloat units)
3364{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003365 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003366}
3367
3368void Context::sampleCoverage(GLclampf value, GLboolean invert)
3369{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003370 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003371}
3372
3373void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3374{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003375 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003376}
3377
3378void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3379{
3380 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3381 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003382 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003383 }
3384
3385 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3386 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003387 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003388 }
3389}
3390
3391void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3392{
3393 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3394 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003395 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003396 }
3397
3398 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3399 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003400 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003401 }
3402}
3403
3404void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3405{
3406 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3407 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003408 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003409 }
3410
3411 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3412 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003414 }
3415}
3416
3417void Context::vertexAttrib1f(GLuint index, GLfloat x)
3418{
3419 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003420 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003421}
3422
3423void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3424{
3425 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003426 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003427}
3428
3429void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3430{
3431 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003432 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003433}
3434
3435void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3436{
3437 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003438 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003439}
3440
3441void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3442{
3443 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003444 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003445}
3446
3447void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3448{
3449 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003450 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003451}
3452
3453void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3454{
3455 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003456 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003457}
3458
3459void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3460{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003461 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003462}
3463
3464void Context::vertexAttribPointer(GLuint index,
3465 GLint size,
3466 GLenum type,
3467 GLboolean normalized,
3468 GLsizei stride,
3469 const GLvoid *ptr)
3470{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003471 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3472 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003473}
3474
3475void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3476{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003477 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003478}
3479
3480void Context::vertexAttribIPointer(GLuint index,
3481 GLint size,
3482 GLenum type,
3483 GLsizei stride,
3484 const GLvoid *pointer)
3485{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003486 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3487 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003488}
3489
3490void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3491{
3492 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003493 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003494}
3495
3496void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3497{
3498 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003499 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003500}
3501
3502void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3503{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003504 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003505}
3506
3507void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3508{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003509 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003510}
3511
3512void Context::debugMessageControl(GLenum source,
3513 GLenum type,
3514 GLenum severity,
3515 GLsizei count,
3516 const GLuint *ids,
3517 GLboolean enabled)
3518{
3519 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3521 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003522}
3523
3524void Context::debugMessageInsert(GLenum source,
3525 GLenum type,
3526 GLuint id,
3527 GLenum severity,
3528 GLsizei length,
3529 const GLchar *buf)
3530{
3531 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003532 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003533}
3534
3535void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003538}
3539
3540GLuint Context::getDebugMessageLog(GLuint count,
3541 GLsizei bufSize,
3542 GLenum *sources,
3543 GLenum *types,
3544 GLuint *ids,
3545 GLenum *severities,
3546 GLsizei *lengths,
3547 GLchar *messageLog)
3548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3550 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003551}
3552
3553void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3554{
3555 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003556 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003557}
3558
3559void Context::popDebugGroup()
3560{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003561 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003562}
3563
Jamie Madill29639852016-09-02 15:00:09 -04003564void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3565{
3566 Buffer *buffer = mGLState.getTargetBuffer(target);
3567 ASSERT(buffer);
3568 handleError(buffer->bufferData(target, data, size, usage));
3569}
3570
3571void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3572{
3573 if (data == nullptr)
3574 {
3575 return;
3576 }
3577
3578 Buffer *buffer = mGLState.getTargetBuffer(target);
3579 ASSERT(buffer);
3580 handleError(buffer->bufferSubData(target, data, size, offset));
3581}
3582
Jamie Madillef300b12016-10-07 15:12:09 -04003583void Context::attachShader(GLuint program, GLuint shader)
3584{
3585 auto programObject = mResourceManager->getProgram(program);
3586 auto shaderObject = mResourceManager->getShader(shader);
3587 ASSERT(programObject && shaderObject);
3588 programObject->attachShader(shaderObject);
3589}
3590
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003591const Workarounds &Context::getWorkarounds() const
3592{
3593 return mWorkarounds;
3594}
3595
Jamie Madillb0817d12016-11-01 15:48:31 -04003596void Context::copyBufferSubData(GLenum readTarget,
3597 GLenum writeTarget,
3598 GLintptr readOffset,
3599 GLintptr writeOffset,
3600 GLsizeiptr size)
3601{
3602 // if size is zero, the copy is a successful no-op
3603 if (size == 0)
3604 {
3605 return;
3606 }
3607
3608 // TODO(jmadill): cache these.
3609 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3610 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3611
3612 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3613}
3614
Jamie Madill01a80ee2016-11-07 12:06:18 -05003615void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3616{
3617 Program *programObject = getProgram(program);
3618 // TODO(jmadill): Re-use this from the validation if possible.
3619 ASSERT(programObject);
3620 programObject->bindAttributeLocation(index, name);
3621}
3622
3623void Context::bindBuffer(GLenum target, GLuint buffer)
3624{
3625 switch (target)
3626 {
3627 case GL_ARRAY_BUFFER:
3628 bindArrayBuffer(buffer);
3629 break;
3630 case GL_ELEMENT_ARRAY_BUFFER:
3631 bindElementArrayBuffer(buffer);
3632 break;
3633 case GL_COPY_READ_BUFFER:
3634 bindCopyReadBuffer(buffer);
3635 break;
3636 case GL_COPY_WRITE_BUFFER:
3637 bindCopyWriteBuffer(buffer);
3638 break;
3639 case GL_PIXEL_PACK_BUFFER:
3640 bindPixelPackBuffer(buffer);
3641 break;
3642 case GL_PIXEL_UNPACK_BUFFER:
3643 bindPixelUnpackBuffer(buffer);
3644 break;
3645 case GL_UNIFORM_BUFFER:
3646 bindGenericUniformBuffer(buffer);
3647 break;
3648 case GL_TRANSFORM_FEEDBACK_BUFFER:
3649 bindGenericTransformFeedbackBuffer(buffer);
3650 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003651 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003652 if (buffer != 0)
3653 {
3654 // Binding buffers to this binding point is not implemented yet.
3655 UNIMPLEMENTED();
3656 }
Geoff Lang3b573612016-10-31 14:08:10 -04003657 break;
3658 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003659 if (buffer != 0)
3660 {
3661 // Binding buffers to this binding point is not implemented yet.
3662 UNIMPLEMENTED();
3663 }
Geoff Lang3b573612016-10-31 14:08:10 -04003664 break;
3665 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003666 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003667 break;
3668 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003669 if (buffer != 0)
3670 {
3671 // Binding buffers to this binding point is not implemented yet.
3672 UNIMPLEMENTED();
3673 }
Geoff Lang3b573612016-10-31 14:08:10 -04003674 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003675
3676 default:
3677 UNREACHABLE();
3678 break;
3679 }
3680}
3681
3682void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3683{
3684 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3685 {
3686 bindReadFramebuffer(framebuffer);
3687 }
3688
3689 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3690 {
3691 bindDrawFramebuffer(framebuffer);
3692 }
3693}
3694
3695void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3696{
3697 ASSERT(target == GL_RENDERBUFFER);
3698 Renderbuffer *object =
3699 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
3700 mGLState.setRenderbufferBinding(object);
3701}
3702
Jamie Madillc29968b2016-01-20 11:17:23 -05003703} // namespace gl