blob: 3ccbeb443f5cd8cae03fa04418d6f0b581981a9e [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{
Corentin Wallezb1d0a2552016-12-19 16:15:54 -0500534 return mResourceManager->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000535}
536
537GLuint Context::createTexture()
538{
539 return mResourceManager->createTexture();
540}
541
542GLuint Context::createRenderbuffer()
543{
544 return mResourceManager->createRenderbuffer();
545}
546
Geoff Lang882033e2014-09-30 11:26:07 -0400547GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400548{
Jamie Madill901b3792016-05-26 09:20:40 -0400549 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400550
Cooper Partind8e62a32015-01-29 15:21:25 -0800551 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400552}
553
Sami Väisänene45e53b2016-05-25 10:36:04 +0300554GLuint Context::createPaths(GLsizei range)
555{
556 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
557 if (resultOrError.isError())
558 {
559 handleError(resultOrError.getError());
560 return 0;
561 }
562 return resultOrError.getResult();
563}
564
Jamie Madill57a89722013-07-02 11:57:03 -0400565GLuint Context::createVertexArray()
566{
Geoff Lang36167ab2015-12-07 10:27:14 -0500567 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
568 mVertexArrayMap[vertexArray] = nullptr;
569 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400570}
571
Jamie Madilldc356042013-07-19 16:36:57 -0400572GLuint Context::createSampler()
573{
574 return mResourceManager->createSampler();
575}
576
Geoff Langc8058452014-02-03 12:04:11 -0500577GLuint Context::createTransformFeedback()
578{
Geoff Lang36167ab2015-12-07 10:27:14 -0500579 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
580 mTransformFeedbackMap[transformFeedback] = nullptr;
581 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500582}
583
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000584// Returns an unused framebuffer name
585GLuint Context::createFramebuffer()
586{
587 GLuint handle = mFramebufferHandleAllocator.allocate();
588
589 mFramebufferMap[handle] = NULL;
590
591 return handle;
592}
593
Jamie Madill33dc8432013-07-26 11:55:05 -0400594GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595{
Jamie Madill33dc8432013-07-26 11:55:05 -0400596 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400598 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000599
600 return handle;
601}
602
603// Returns an unused query name
604GLuint Context::createQuery()
605{
606 GLuint handle = mQueryHandleAllocator.allocate();
607
608 mQueryMap[handle] = NULL;
609
610 return handle;
611}
612
613void Context::deleteBuffer(GLuint buffer)
614{
615 if (mResourceManager->getBuffer(buffer))
616 {
617 detachBuffer(buffer);
618 }
Jamie Madill893ab082014-05-16 16:56:10 -0400619
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620 mResourceManager->deleteBuffer(buffer);
621}
622
623void Context::deleteShader(GLuint shader)
624{
625 mResourceManager->deleteShader(shader);
626}
627
628void Context::deleteProgram(GLuint program)
629{
630 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631}
632
633void Context::deleteTexture(GLuint texture)
634{
635 if (mResourceManager->getTexture(texture))
636 {
637 detachTexture(texture);
638 }
639
640 mResourceManager->deleteTexture(texture);
641}
642
643void Context::deleteRenderbuffer(GLuint renderbuffer)
644{
645 if (mResourceManager->getRenderbuffer(renderbuffer))
646 {
647 detachRenderbuffer(renderbuffer);
648 }
Jamie Madill893ab082014-05-16 16:56:10 -0400649
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000650 mResourceManager->deleteRenderbuffer(renderbuffer);
651}
652
Jamie Madillcd055f82013-07-26 11:55:15 -0400653void Context::deleteFenceSync(GLsync fenceSync)
654{
655 // The spec specifies the underlying Fence object is not deleted until all current
656 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
657 // and since our API is currently designed for being called from a single thread, we can delete
658 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700659 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400660}
661
Sami Väisänene45e53b2016-05-25 10:36:04 +0300662void Context::deletePaths(GLuint first, GLsizei range)
663{
664 mResourceManager->deletePaths(first, range);
665}
666
667bool Context::hasPathData(GLuint path) const
668{
669 const auto *pathObj = mResourceManager->getPath(path);
670 if (pathObj == nullptr)
671 return false;
672
673 return pathObj->hasPathData();
674}
675
676bool Context::hasPath(GLuint path) const
677{
678 return mResourceManager->hasPath(path);
679}
680
681void Context::setPathCommands(GLuint path,
682 GLsizei numCommands,
683 const GLubyte *commands,
684 GLsizei numCoords,
685 GLenum coordType,
686 const void *coords)
687{
688 auto *pathObject = mResourceManager->getPath(path);
689
690 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
691}
692
693void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
694{
695 auto *pathObj = mResourceManager->getPath(path);
696
697 switch (pname)
698 {
699 case GL_PATH_STROKE_WIDTH_CHROMIUM:
700 pathObj->setStrokeWidth(value);
701 break;
702 case GL_PATH_END_CAPS_CHROMIUM:
703 pathObj->setEndCaps(static_cast<GLenum>(value));
704 break;
705 case GL_PATH_JOIN_STYLE_CHROMIUM:
706 pathObj->setJoinStyle(static_cast<GLenum>(value));
707 break;
708 case GL_PATH_MITER_LIMIT_CHROMIUM:
709 pathObj->setMiterLimit(value);
710 break;
711 case GL_PATH_STROKE_BOUND_CHROMIUM:
712 pathObj->setStrokeBound(value);
713 break;
714 default:
715 UNREACHABLE();
716 break;
717 }
718}
719
720void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
721{
722 const auto *pathObj = mResourceManager->getPath(path);
723
724 switch (pname)
725 {
726 case GL_PATH_STROKE_WIDTH_CHROMIUM:
727 *value = pathObj->getStrokeWidth();
728 break;
729 case GL_PATH_END_CAPS_CHROMIUM:
730 *value = static_cast<GLfloat>(pathObj->getEndCaps());
731 break;
732 case GL_PATH_JOIN_STYLE_CHROMIUM:
733 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
734 break;
735 case GL_PATH_MITER_LIMIT_CHROMIUM:
736 *value = pathObj->getMiterLimit();
737 break;
738 case GL_PATH_STROKE_BOUND_CHROMIUM:
739 *value = pathObj->getStrokeBound();
740 break;
741 default:
742 UNREACHABLE();
743 break;
744 }
745}
746
747void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
748{
749 mGLState.setPathStencilFunc(func, ref, mask);
750}
751
Jamie Madill57a89722013-07-02 11:57:03 -0400752void Context::deleteVertexArray(GLuint vertexArray)
753{
Geoff Lang36167ab2015-12-07 10:27:14 -0500754 auto iter = mVertexArrayMap.find(vertexArray);
755 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000756 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500757 VertexArray *vertexArrayObject = iter->second;
758 if (vertexArrayObject != nullptr)
759 {
760 detachVertexArray(vertexArray);
761 delete vertexArrayObject;
762 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000763
Geoff Lang36167ab2015-12-07 10:27:14 -0500764 mVertexArrayMap.erase(iter);
765 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400766 }
767}
768
Jamie Madilldc356042013-07-19 16:36:57 -0400769void Context::deleteSampler(GLuint sampler)
770{
771 if (mResourceManager->getSampler(sampler))
772 {
773 detachSampler(sampler);
774 }
775
776 mResourceManager->deleteSampler(sampler);
777}
778
Geoff Langc8058452014-02-03 12:04:11 -0500779void Context::deleteTransformFeedback(GLuint transformFeedback)
780{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500781 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500782 if (iter != mTransformFeedbackMap.end())
783 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500784 TransformFeedback *transformFeedbackObject = iter->second;
785 if (transformFeedbackObject != nullptr)
786 {
787 detachTransformFeedback(transformFeedback);
788 transformFeedbackObject->release();
789 }
790
Geoff Lang50b3fe82015-12-08 14:49:12 +0000791 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500792 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500793 }
794}
795
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796void Context::deleteFramebuffer(GLuint framebuffer)
797{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500798 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000799
800 if (framebufferObject != mFramebufferMap.end())
801 {
802 detachFramebuffer(framebuffer);
803
804 mFramebufferHandleAllocator.release(framebufferObject->first);
805 delete framebufferObject->second;
806 mFramebufferMap.erase(framebufferObject);
807 }
808}
809
Jamie Madill33dc8432013-07-26 11:55:05 -0400810void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000811{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500812 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813
Jamie Madill33dc8432013-07-26 11:55:05 -0400814 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400816 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000817 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400818 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000819 }
820}
821
822void Context::deleteQuery(GLuint query)
823{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500824 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825 if (queryObject != mQueryMap.end())
826 {
827 mQueryHandleAllocator.release(queryObject->first);
828 if (queryObject->second)
829 {
830 queryObject->second->release();
831 }
832 mQueryMap.erase(queryObject);
833 }
834}
835
Geoff Lang70d0f492015-12-10 17:45:46 -0500836Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837{
838 return mResourceManager->getBuffer(handle);
839}
840
Jamie Madill570f7c82014-07-03 10:38:54 -0400841Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000842{
843 return mResourceManager->getTexture(handle);
844}
845
Geoff Lang70d0f492015-12-10 17:45:46 -0500846Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847{
848 return mResourceManager->getRenderbuffer(handle);
849}
850
Jamie Madillcd055f82013-07-26 11:55:15 -0400851FenceSync *Context::getFenceSync(GLsync handle) const
852{
Minmin Gong794e0002015-04-07 18:31:54 -0700853 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400854}
855
Jamie Madill57a89722013-07-02 11:57:03 -0400856VertexArray *Context::getVertexArray(GLuint handle) const
857{
858 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500859 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400860}
861
Jamie Madilldc356042013-07-19 16:36:57 -0400862Sampler *Context::getSampler(GLuint handle) const
863{
864 return mResourceManager->getSampler(handle);
865}
866
Geoff Langc8058452014-02-03 12:04:11 -0500867TransformFeedback *Context::getTransformFeedback(GLuint handle) const
868{
Geoff Lang36167ab2015-12-07 10:27:14 -0500869 auto iter = mTransformFeedbackMap.find(handle);
870 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500871}
872
Geoff Lang70d0f492015-12-10 17:45:46 -0500873LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
874{
875 switch (identifier)
876 {
877 case GL_BUFFER:
878 return getBuffer(name);
879 case GL_SHADER:
880 return getShader(name);
881 case GL_PROGRAM:
882 return getProgram(name);
883 case GL_VERTEX_ARRAY:
884 return getVertexArray(name);
885 case GL_QUERY:
886 return getQuery(name);
887 case GL_TRANSFORM_FEEDBACK:
888 return getTransformFeedback(name);
889 case GL_SAMPLER:
890 return getSampler(name);
891 case GL_TEXTURE:
892 return getTexture(name);
893 case GL_RENDERBUFFER:
894 return getRenderbuffer(name);
895 case GL_FRAMEBUFFER:
896 return getFramebuffer(name);
897 default:
898 UNREACHABLE();
899 return nullptr;
900 }
901}
902
903LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
904{
905 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
906}
907
Martin Radev9d901792016-07-15 15:58:58 +0300908void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
909{
910 LabeledObject *object = getLabeledObject(identifier, name);
911 ASSERT(object != nullptr);
912
913 std::string labelName = GetObjectLabelFromPointer(length, label);
914 object->setLabel(labelName);
915}
916
917void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
918{
919 LabeledObject *object = getLabeledObjectFromPtr(ptr);
920 ASSERT(object != nullptr);
921
922 std::string labelName = GetObjectLabelFromPointer(length, label);
923 object->setLabel(labelName);
924}
925
926void Context::getObjectLabel(GLenum identifier,
927 GLuint name,
928 GLsizei bufSize,
929 GLsizei *length,
930 GLchar *label) const
931{
932 LabeledObject *object = getLabeledObject(identifier, name);
933 ASSERT(object != nullptr);
934
935 const std::string &objectLabel = object->getLabel();
936 GetObjectLabelBase(objectLabel, bufSize, length, label);
937}
938
939void Context::getObjectPtrLabel(const void *ptr,
940 GLsizei bufSize,
941 GLsizei *length,
942 GLchar *label) const
943{
944 LabeledObject *object = getLabeledObjectFromPtr(ptr);
945 ASSERT(object != nullptr);
946
947 const std::string &objectLabel = object->getLabel();
948 GetObjectLabelBase(objectLabel, bufSize, length, label);
949}
950
Jamie Madilldc356042013-07-19 16:36:57 -0400951bool Context::isSampler(GLuint samplerName) const
952{
953 return mResourceManager->isSampler(samplerName);
954}
955
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500956void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000957{
Jamie Madill901b3792016-05-26 09:20:40 -0400958 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700959 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000960}
961
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800962void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
963{
964 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
965 mGLState.setDrawIndirectBufferBinding(buffer);
966}
967
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500968void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000969{
Jamie Madill901b3792016-05-26 09:20:40 -0400970 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700971 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000972}
973
Jamie Madilldedd7b92014-11-05 16:30:36 -0500974void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000975{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500976 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977
Jamie Madilldedd7b92014-11-05 16:30:36 -0500978 if (handle == 0)
979 {
980 texture = mZeroTextures[target].get();
981 }
982 else
983 {
Jamie Madill901b3792016-05-26 09:20:40 -0400984 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500985 }
986
987 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700988 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000989}
990
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500991void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500993 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700994 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995}
996
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500997void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000998{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500999 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001000 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001001}
1002
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001003void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001004{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001005 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001006 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001007}
1008
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001009void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001010{
Geoff Lang76b10c92014-09-05 16:28:14 -04001011 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001012 Sampler *sampler =
1013 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001014 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001015}
1016
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001017void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001018{
Jamie Madill901b3792016-05-26 09:20:40 -04001019 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001020 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001021}
1022
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001023void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1024 GLuint index,
1025 GLintptr offset,
1026 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001027{
Jamie Madill901b3792016-05-26 09:20:40 -04001028 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001029 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001030}
1031
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001032void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001033{
Jamie Madill901b3792016-05-26 09:20:40 -04001034 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001035 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001036}
1037
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001038void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1039 GLuint index,
1040 GLintptr offset,
1041 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001042{
Jamie Madill901b3792016-05-26 09:20:40 -04001043 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001044 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001045}
1046
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001047void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001048{
Jamie Madill901b3792016-05-26 09:20:40 -04001049 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001050 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001051}
1052
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001053void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001054{
Jamie Madill901b3792016-05-26 09:20:40 -04001055 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001056 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001057}
1058
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001059void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001060{
Jamie Madill901b3792016-05-26 09:20:40 -04001061 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001062 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001063}
1064
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001065void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001066{
Jamie Madill901b3792016-05-26 09:20:40 -04001067 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001068 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001069}
1070
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001071void Context::useProgram(GLuint program)
1072{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001073 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001074}
1075
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001076void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001077{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001078 TransformFeedback *transformFeedback =
1079 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001080 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001081}
1082
Geoff Lang5aad9672014-09-08 11:10:42 -04001083Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001084{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001086 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001087
Geoff Lang5aad9672014-09-08 11:10:42 -04001088 // begin query
1089 Error error = queryObject->begin();
1090 if (error.isError())
1091 {
1092 return error;
1093 }
1094
1095 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001096 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001097
He Yunchaoacd18982017-01-04 10:46:42 +08001098 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001099}
1100
Geoff Lang5aad9672014-09-08 11:10:42 -04001101Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001102{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001103 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001104 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001105
Geoff Lang5aad9672014-09-08 11:10:42 -04001106 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001107
Geoff Lang5aad9672014-09-08 11:10:42 -04001108 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001109 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001110
1111 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001112}
1113
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001114Error Context::queryCounter(GLuint id, GLenum target)
1115{
1116 ASSERT(target == GL_TIMESTAMP_EXT);
1117
1118 Query *queryObject = getQuery(id, true, target);
1119 ASSERT(queryObject);
1120
1121 return queryObject->queryCounter();
1122}
1123
1124void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1125{
1126 switch (pname)
1127 {
1128 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001129 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001130 break;
1131 case GL_QUERY_COUNTER_BITS_EXT:
1132 switch (target)
1133 {
1134 case GL_TIME_ELAPSED_EXT:
1135 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1136 break;
1137 case GL_TIMESTAMP_EXT:
1138 params[0] = getExtensions().queryCounterBitsTimestamp;
1139 break;
1140 default:
1141 UNREACHABLE();
1142 params[0] = 0;
1143 break;
1144 }
1145 break;
1146 default:
1147 UNREACHABLE();
1148 return;
1149 }
1150}
1151
Geoff Lang2186c382016-10-14 10:54:54 -04001152void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001153{
Geoff Lang2186c382016-10-14 10:54:54 -04001154 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001155}
1156
Geoff Lang2186c382016-10-14 10:54:54 -04001157void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001158{
Geoff Lang2186c382016-10-14 10:54:54 -04001159 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001160}
1161
Geoff Lang2186c382016-10-14 10:54:54 -04001162void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001163{
Geoff Lang2186c382016-10-14 10:54:54 -04001164 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001165}
1166
Geoff Lang2186c382016-10-14 10:54:54 -04001167void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001168{
Geoff Lang2186c382016-10-14 10:54:54 -04001169 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001170}
1171
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001172Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001174 auto framebufferIt = mFramebufferMap.find(handle);
1175 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001176}
1177
Jamie Madill33dc8432013-07-26 11:55:05 -04001178FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001180 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181
Jamie Madill33dc8432013-07-26 11:55:05 -04001182 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001183 {
1184 return NULL;
1185 }
1186 else
1187 {
1188 return fence->second;
1189 }
1190}
1191
1192Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1193{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001194 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001195
1196 if (query == mQueryMap.end())
1197 {
1198 return NULL;
1199 }
1200 else
1201 {
1202 if (!query->second && create)
1203 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001204 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001205 query->second->addRef();
1206 }
1207 return query->second;
1208 }
1209}
1210
Geoff Lang70d0f492015-12-10 17:45:46 -05001211Query *Context::getQuery(GLuint handle) const
1212{
1213 auto iter = mQueryMap.find(handle);
1214 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1215}
1216
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001217Texture *Context::getTargetTexture(GLenum target) const
1218{
Ian Ewellbda75592016-04-18 17:25:54 -04001219 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001220 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001221}
1222
Geoff Lang76b10c92014-09-05 16:28:14 -04001223Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001224{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001225 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226}
1227
Geoff Lang492a7e42014-11-05 13:27:06 -05001228Compiler *Context::getCompiler() const
1229{
1230 return mCompiler;
1231}
1232
Jamie Madill893ab082014-05-16 16:56:10 -04001233void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001234{
1235 switch (pname)
1236 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001237 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001238 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001239 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001240 mGLState.getBooleanv(pname, params);
1241 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243}
1244
Jamie Madill893ab082014-05-16 16:56:10 -04001245void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246{
Shannon Woods53a94a82014-06-24 15:20:36 -04001247 // Queries about context capabilities and maximums are answered by Context.
1248 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001249 switch (pname)
1250 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001251 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001252 params[0] = mCaps.minAliasedLineWidth;
1253 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001254 break;
1255 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001256 params[0] = mCaps.minAliasedPointSize;
1257 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001258 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001259 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001260 ASSERT(mExtensions.textureFilterAnisotropic);
1261 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001262 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001263 case GL_MAX_TEXTURE_LOD_BIAS:
1264 *params = mCaps.maxLODBias;
1265 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001266
1267 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1268 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1269 {
1270 ASSERT(mExtensions.pathRendering);
1271 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1272 memcpy(params, m, 16 * sizeof(GLfloat));
1273 }
1274 break;
1275
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001277 mGLState.getFloatv(pname, params);
1278 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280}
1281
Jamie Madill893ab082014-05-16 16:56:10 -04001282void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001283{
Shannon Woods53a94a82014-06-24 15:20:36 -04001284 // Queries about context capabilities and maximums are answered by Context.
1285 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001286
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001287 switch (pname)
1288 {
Geoff Lang301d1612014-07-09 10:34:37 -04001289 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1290 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1291 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001292 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1293 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1294 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001295 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1296 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1297 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001298 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001299 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1300 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1301 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001302 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001303 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001304 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1305 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1306 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1307 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001308 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1309 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001310 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1311 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001312 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001313 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1314 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1315 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1316 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001317 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001318 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001319 break;
1320 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001321 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001322 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001323 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1324 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001325 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1326 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1327 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001328 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1329 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1330 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001331 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 case GL_MAX_VIEWPORT_DIMS:
1333 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001334 params[0] = mCaps.maxViewportWidth;
1335 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001336 }
1337 break;
1338 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001339 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001340 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001341 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1342 *params = mResetStrategy;
1343 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001344 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001345 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001346 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001347 case GL_SHADER_BINARY_FORMATS:
1348 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1349 break;
1350 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001351 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001352 break;
1353 case GL_PROGRAM_BINARY_FORMATS:
1354 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001355 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001356 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001357 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001358 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001359
1360 // GL_KHR_debug
1361 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1362 *params = mExtensions.maxDebugMessageLength;
1363 break;
1364 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1365 *params = mExtensions.maxDebugLoggedMessages;
1366 break;
1367 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1368 *params = mExtensions.maxDebugGroupStackDepth;
1369 break;
1370 case GL_MAX_LABEL_LENGTH:
1371 *params = mExtensions.maxLabelLength;
1372 break;
1373
Ian Ewell53f59f42016-01-28 17:36:55 -05001374 // GL_EXT_disjoint_timer_query
1375 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001376 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001377 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001378 case GL_MAX_FRAMEBUFFER_WIDTH:
1379 *params = mCaps.maxFramebufferWidth;
1380 break;
1381 case GL_MAX_FRAMEBUFFER_HEIGHT:
1382 *params = mCaps.maxFramebufferHeight;
1383 break;
1384 case GL_MAX_FRAMEBUFFER_SAMPLES:
1385 *params = mCaps.maxFramebufferSamples;
1386 break;
1387 case GL_MAX_SAMPLE_MASK_WORDS:
1388 *params = mCaps.maxSampleMaskWords;
1389 break;
1390 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1391 *params = mCaps.maxColorTextureSamples;
1392 break;
1393 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1394 *params = mCaps.maxDepthTextureSamples;
1395 break;
1396 case GL_MAX_INTEGER_SAMPLES:
1397 *params = mCaps.maxIntegerSamples;
1398 break;
1399 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1400 *params = mCaps.maxVertexAttribRelativeOffset;
1401 break;
1402 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1403 *params = mCaps.maxVertexAttribBindings;
1404 break;
1405 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1406 *params = mCaps.maxVertexAttribStride;
1407 break;
1408 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1409 *params = mCaps.maxVertexAtomicCounterBuffers;
1410 break;
1411 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1412 *params = mCaps.maxVertexAtomicCounters;
1413 break;
1414 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1415 *params = mCaps.maxVertexImageUniforms;
1416 break;
1417 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1418 *params = mCaps.maxVertexShaderStorageBlocks;
1419 break;
1420 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1421 *params = mCaps.maxFragmentAtomicCounterBuffers;
1422 break;
1423 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1424 *params = mCaps.maxFragmentAtomicCounters;
1425 break;
1426 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1427 *params = mCaps.maxFragmentImageUniforms;
1428 break;
1429 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1430 *params = mCaps.maxFragmentShaderStorageBlocks;
1431 break;
1432 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1433 *params = mCaps.minProgramTextureGatherOffset;
1434 break;
1435 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1436 *params = mCaps.maxProgramTextureGatherOffset;
1437 break;
1438 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1439 *params = mCaps.maxComputeWorkGroupInvocations;
1440 break;
1441 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1442 *params = mCaps.maxComputeUniformBlocks;
1443 break;
1444 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1445 *params = mCaps.maxComputeTextureImageUnits;
1446 break;
1447 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1448 *params = mCaps.maxComputeSharedMemorySize;
1449 break;
1450 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1451 *params = mCaps.maxComputeUniformComponents;
1452 break;
1453 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1454 *params = mCaps.maxComputeAtomicCounterBuffers;
1455 break;
1456 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1457 *params = mCaps.maxComputeAtomicCounters;
1458 break;
1459 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1460 *params = mCaps.maxComputeImageUniforms;
1461 break;
1462 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1463 *params = mCaps.maxCombinedComputeUniformComponents;
1464 break;
1465 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1466 *params = mCaps.maxComputeShaderStorageBlocks;
1467 break;
1468 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1469 *params = mCaps.maxCombinedShaderOutputResources;
1470 break;
1471 case GL_MAX_UNIFORM_LOCATIONS:
1472 *params = mCaps.maxUniformLocations;
1473 break;
1474 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1475 *params = mCaps.maxAtomicCounterBufferBindings;
1476 break;
1477 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1478 *params = mCaps.maxAtomicCounterBufferSize;
1479 break;
1480 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1481 *params = mCaps.maxCombinedAtomicCounterBuffers;
1482 break;
1483 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1484 *params = mCaps.maxCombinedAtomicCounters;
1485 break;
1486 case GL_MAX_IMAGE_UNITS:
1487 *params = mCaps.maxImageUnits;
1488 break;
1489 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1490 *params = mCaps.maxCombinedImageUniforms;
1491 break;
1492 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1493 *params = mCaps.maxShaderStorageBufferBindings;
1494 break;
1495 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1496 *params = mCaps.maxCombinedShaderStorageBlocks;
1497 break;
1498 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1499 *params = mCaps.shaderStorageBufferOffsetAlignment;
1500 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001501 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001502 mGLState.getIntegerv(mState, pname, params);
1503 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001504 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001505}
1506
Jamie Madill893ab082014-05-16 16:56:10 -04001507void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001508{
Shannon Woods53a94a82014-06-24 15:20:36 -04001509 // Queries about context capabilities and maximums are answered by Context.
1510 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001511 switch (pname)
1512 {
1513 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001514 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001515 break;
1516 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001517 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001518 break;
1519 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001520 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001521 break;
1522 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001523 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001524 break;
1525 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001526 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001527 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001528
1529 // GL_EXT_disjoint_timer_query
1530 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001531 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001532 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001533
1534 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1535 *params = mCaps.maxShaderStorageBlockSize;
1536 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001537 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001538 UNREACHABLE();
1539 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001540 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001541}
1542
Geoff Lang70d0f492015-12-10 17:45:46 -05001543void Context::getPointerv(GLenum pname, void **params) const
1544{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001545 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001546}
1547
Martin Radev66fb8202016-07-28 11:45:20 +03001548void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001549{
Shannon Woods53a94a82014-06-24 15:20:36 -04001550 // Queries about context capabilities and maximums are answered by Context.
1551 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001552
1553 GLenum nativeType;
1554 unsigned int numParams;
1555 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1556 ASSERT(queryStatus);
1557
1558 if (nativeType == GL_INT)
1559 {
1560 switch (target)
1561 {
1562 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1563 ASSERT(index < 3u);
1564 *data = mCaps.maxComputeWorkGroupCount[index];
1565 break;
1566 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1567 ASSERT(index < 3u);
1568 *data = mCaps.maxComputeWorkGroupSize[index];
1569 break;
1570 default:
1571 mGLState.getIntegeri_v(target, index, data);
1572 }
1573 }
1574 else
1575 {
1576 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1577 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001578}
1579
Martin Radev66fb8202016-07-28 11:45:20 +03001580void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001581{
Shannon Woods53a94a82014-06-24 15:20:36 -04001582 // Queries about context capabilities and maximums are answered by Context.
1583 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001584
1585 GLenum nativeType;
1586 unsigned int numParams;
1587 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1588 ASSERT(queryStatus);
1589
1590 if (nativeType == GL_INT_64_ANGLEX)
1591 {
1592 mGLState.getInteger64i_v(target, index, data);
1593 }
1594 else
1595 {
1596 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1597 }
1598}
1599
1600void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1601{
1602 // Queries about context capabilities and maximums are answered by Context.
1603 // Queries about current GL state values are answered by State.
1604
1605 GLenum nativeType;
1606 unsigned int numParams;
1607 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1608 ASSERT(queryStatus);
1609
1610 if (nativeType == GL_BOOL)
1611 {
1612 mGLState.getBooleani_v(target, index, data);
1613 }
1614 else
1615 {
1616 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1617 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001618}
1619
Jamie Madill675fe712016-12-19 13:07:54 -05001620void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001621{
Jamie Madill1b94d432015-08-07 13:23:23 -04001622 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001623 auto error = mImplementation->drawArrays(mode, first, count);
1624 handleError(error);
1625 if (!error.isError())
1626 {
1627 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1628 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001629}
1630
Jamie Madill675fe712016-12-19 13:07:54 -05001631void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001632{
1633 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001634 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1635 handleError(error);
1636 if (!error.isError())
1637 {
1638 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1639 }
Geoff Langf6db0982015-08-25 13:04:00 -04001640}
1641
Jamie Madill675fe712016-12-19 13:07:54 -05001642void Context::drawElements(GLenum mode,
1643 GLsizei count,
1644 GLenum type,
1645 const GLvoid *indices,
1646 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001647{
Jamie Madill1b94d432015-08-07 13:23:23 -04001648 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001649 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001650}
1651
Jamie Madill675fe712016-12-19 13:07:54 -05001652void Context::drawElementsInstanced(GLenum mode,
1653 GLsizei count,
1654 GLenum type,
1655 const GLvoid *indices,
1656 GLsizei instances,
1657 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001658{
1659 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001660 handleError(
1661 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001662}
1663
Jamie Madill675fe712016-12-19 13:07:54 -05001664void Context::drawRangeElements(GLenum mode,
1665 GLuint start,
1666 GLuint end,
1667 GLsizei count,
1668 GLenum type,
1669 const GLvoid *indices,
1670 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001671{
1672 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001673 handleError(
1674 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001675}
1676
Jiajia Qind9671222016-11-29 16:30:31 +08001677void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1678{
1679 syncRendererState();
1680 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1681}
1682
1683void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1684{
1685 syncRendererState();
1686 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1687}
1688
Jamie Madill675fe712016-12-19 13:07:54 -05001689void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001690{
Jamie Madill675fe712016-12-19 13:07:54 -05001691 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001692}
1693
Jamie Madill675fe712016-12-19 13:07:54 -05001694void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001695{
Jamie Madill675fe712016-12-19 13:07:54 -05001696 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001697}
1698
Austin Kinross6ee1e782015-05-29 17:05:37 -07001699void Context::insertEventMarker(GLsizei length, const char *marker)
1700{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001701 ASSERT(mImplementation);
1702 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001703}
1704
1705void Context::pushGroupMarker(GLsizei length, const char *marker)
1706{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001707 ASSERT(mImplementation);
1708 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001709}
1710
1711void Context::popGroupMarker()
1712{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001713 ASSERT(mImplementation);
1714 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001715}
1716
Geoff Langd8605522016-04-13 10:19:12 -04001717void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1718{
1719 Program *programObject = getProgram(program);
1720 ASSERT(programObject);
1721
1722 programObject->bindUniformLocation(location, name);
1723}
1724
Sami Väisänena797e062016-05-12 15:23:40 +03001725void Context::setCoverageModulation(GLenum components)
1726{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001727 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001728}
1729
Sami Väisänene45e53b2016-05-25 10:36:04 +03001730void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1731{
1732 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1733}
1734
1735void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1736{
1737 GLfloat I[16];
1738 angle::Matrix<GLfloat>::setToIdentity(I);
1739
1740 mGLState.loadPathRenderingMatrix(matrixMode, I);
1741}
1742
1743void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1744{
1745 const auto *pathObj = mResourceManager->getPath(path);
1746 if (!pathObj)
1747 return;
1748
1749 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1750 syncRendererState();
1751
1752 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1753}
1754
1755void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1756{
1757 const auto *pathObj = mResourceManager->getPath(path);
1758 if (!pathObj)
1759 return;
1760
1761 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1762 syncRendererState();
1763
1764 mImplementation->stencilStrokePath(pathObj, reference, mask);
1765}
1766
1767void Context::coverFillPath(GLuint path, GLenum coverMode)
1768{
1769 const auto *pathObj = mResourceManager->getPath(path);
1770 if (!pathObj)
1771 return;
1772
1773 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1774 syncRendererState();
1775
1776 mImplementation->coverFillPath(pathObj, coverMode);
1777}
1778
1779void Context::coverStrokePath(GLuint path, GLenum coverMode)
1780{
1781 const auto *pathObj = mResourceManager->getPath(path);
1782 if (!pathObj)
1783 return;
1784
1785 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1786 syncRendererState();
1787
1788 mImplementation->coverStrokePath(pathObj, coverMode);
1789}
1790
1791void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1792{
1793 const auto *pathObj = mResourceManager->getPath(path);
1794 if (!pathObj)
1795 return;
1796
1797 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1798 syncRendererState();
1799
1800 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1801}
1802
1803void Context::stencilThenCoverStrokePath(GLuint path,
1804 GLint reference,
1805 GLuint mask,
1806 GLenum coverMode)
1807{
1808 const auto *pathObj = mResourceManager->getPath(path);
1809 if (!pathObj)
1810 return;
1811
1812 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1813 syncRendererState();
1814
1815 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1816}
1817
Sami Väisänend59ca052016-06-21 16:10:00 +03001818void Context::coverFillPathInstanced(GLsizei numPaths,
1819 GLenum pathNameType,
1820 const void *paths,
1821 GLuint pathBase,
1822 GLenum coverMode,
1823 GLenum transformType,
1824 const GLfloat *transformValues)
1825{
1826 const auto &pathObjects =
1827 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1828
1829 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1830 syncRendererState();
1831
1832 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1833}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001834
Sami Väisänend59ca052016-06-21 16:10:00 +03001835void Context::coverStrokePathInstanced(GLsizei numPaths,
1836 GLenum pathNameType,
1837 const void *paths,
1838 GLuint pathBase,
1839 GLenum coverMode,
1840 GLenum transformType,
1841 const GLfloat *transformValues)
1842{
1843 const auto &pathObjects =
1844 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1845
1846 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1847 syncRendererState();
1848
1849 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1850 transformValues);
1851}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001852
Sami Väisänend59ca052016-06-21 16:10:00 +03001853void Context::stencilFillPathInstanced(GLsizei numPaths,
1854 GLenum pathNameType,
1855 const void *paths,
1856 GLuint pathBase,
1857 GLenum fillMode,
1858 GLuint mask,
1859 GLenum transformType,
1860 const GLfloat *transformValues)
1861{
1862 const auto &pathObjects =
1863 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1864
1865 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1866 syncRendererState();
1867
1868 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1869 transformValues);
1870}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001871
Sami Väisänend59ca052016-06-21 16:10:00 +03001872void Context::stencilStrokePathInstanced(GLsizei numPaths,
1873 GLenum pathNameType,
1874 const void *paths,
1875 GLuint pathBase,
1876 GLint reference,
1877 GLuint mask,
1878 GLenum transformType,
1879 const GLfloat *transformValues)
1880{
1881 const auto &pathObjects =
1882 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1883
1884 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1885 syncRendererState();
1886
1887 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1888 transformValues);
1889}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001890
Sami Väisänend59ca052016-06-21 16:10:00 +03001891void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1892 GLenum pathNameType,
1893 const void *paths,
1894 GLuint pathBase,
1895 GLenum fillMode,
1896 GLuint mask,
1897 GLenum coverMode,
1898 GLenum transformType,
1899 const GLfloat *transformValues)
1900{
1901 const auto &pathObjects =
1902 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1903
1904 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1905 syncRendererState();
1906
1907 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1908 transformType, transformValues);
1909}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001910
Sami Väisänend59ca052016-06-21 16:10:00 +03001911void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1912 GLenum pathNameType,
1913 const void *paths,
1914 GLuint pathBase,
1915 GLint reference,
1916 GLuint mask,
1917 GLenum coverMode,
1918 GLenum transformType,
1919 const GLfloat *transformValues)
1920{
1921 const auto &pathObjects =
1922 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1923
1924 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1925 syncRendererState();
1926
1927 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1928 transformType, transformValues);
1929}
1930
Sami Väisänen46eaa942016-06-29 10:26:37 +03001931void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1932{
1933 auto *programObject = getProgram(program);
1934
1935 programObject->bindFragmentInputLocation(location, name);
1936}
1937
1938void Context::programPathFragmentInputGen(GLuint program,
1939 GLint location,
1940 GLenum genMode,
1941 GLint components,
1942 const GLfloat *coeffs)
1943{
1944 auto *programObject = getProgram(program);
1945
1946 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1947}
1948
Jamie Madill437fa652016-05-03 15:13:24 -04001949void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001950{
Geoff Langda5777c2014-07-11 09:52:58 -04001951 if (error.isError())
1952 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001953 GLenum code = error.getCode();
1954 mErrors.insert(code);
1955 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1956 {
1957 markContextLost();
1958 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001959
1960 if (!error.getMessage().empty())
1961 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001962 auto *debug = &mGLState.getDebug();
1963 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1964 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001965 }
Geoff Langda5777c2014-07-11 09:52:58 -04001966 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001967}
1968
1969// Get one of the recorded errors and clear its flag, if any.
1970// [OpenGL ES 2.0.24] section 2.5 page 13.
1971GLenum Context::getError()
1972{
Geoff Langda5777c2014-07-11 09:52:58 -04001973 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001974 {
Geoff Langda5777c2014-07-11 09:52:58 -04001975 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001976 }
Geoff Langda5777c2014-07-11 09:52:58 -04001977 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001978 {
Geoff Langda5777c2014-07-11 09:52:58 -04001979 GLenum error = *mErrors.begin();
1980 mErrors.erase(mErrors.begin());
1981 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001982 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001983}
1984
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001985// NOTE: this function should not assume that this context is current!
1986void Context::markContextLost()
1987{
1988 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001989 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001990 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001991 mContextLostForced = true;
1992 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001993 mContextLost = true;
1994}
1995
1996bool Context::isContextLost()
1997{
1998 return mContextLost;
1999}
2000
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002001GLenum Context::getResetStatus()
2002{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002003 // Even if the application doesn't want to know about resets, we want to know
2004 // as it will allow us to skip all the calls.
2005 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002006 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002007 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002008 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002009 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002010 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002011
2012 // EXT_robustness, section 2.6: If the reset notification behavior is
2013 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2014 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2015 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002016 }
2017
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002018 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2019 // status should be returned at least once, and GL_NO_ERROR should be returned
2020 // once the device has finished resetting.
2021 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002022 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002023 ASSERT(mResetStatus == GL_NO_ERROR);
2024 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002025
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002026 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002027 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002028 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002029 }
2030 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002031 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002032 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002033 // If markContextLost was used to mark the context lost then
2034 // assume that is not recoverable, and continue to report the
2035 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002036 mResetStatus = mImplementation->getResetStatus();
2037 }
Jamie Madill893ab082014-05-16 16:56:10 -04002038
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002039 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002040}
2041
2042bool Context::isResetNotificationEnabled()
2043{
2044 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2045}
2046
Corentin Walleze3b10e82015-05-20 11:06:25 -04002047const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002048{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002049 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002050}
2051
2052EGLenum Context::getClientType() const
2053{
2054 return mClientType;
2055}
2056
2057EGLenum Context::getRenderBuffer() const
2058{
Corentin Wallez37c39792015-08-20 14:19:46 -04002059 auto framebufferIt = mFramebufferMap.find(0);
2060 if (framebufferIt != mFramebufferMap.end())
2061 {
2062 const Framebuffer *framebuffer = framebufferIt->second;
2063 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2064
2065 ASSERT(backAttachment != nullptr);
2066 return backAttachment->getSurface()->getRenderBuffer();
2067 }
2068 else
2069 {
2070 return EGL_NONE;
2071 }
Régis Fénéon83107972015-02-05 12:57:44 +01002072}
2073
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002074VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002075{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002076 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002077 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2078 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002079 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002080 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2081
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002082 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002083 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002084
2085 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002086}
2087
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002088TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002089{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002090 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002091 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2092 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002093 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002094 transformFeedback =
2095 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002096 transformFeedback->addRef();
2097 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002098 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002099
2100 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002101}
2102
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002103Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2104{
2105 // Can be called from Bind without a prior call to Gen.
2106 auto framebufferIt = mFramebufferMap.find(framebuffer);
2107 bool neverCreated = framebufferIt == mFramebufferMap.end();
2108 if (neverCreated || framebufferIt->second == nullptr)
2109 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002110 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002111 if (neverCreated)
2112 {
2113 mFramebufferHandleAllocator.reserve(framebuffer);
2114 mFramebufferMap[framebuffer] = newFBO;
2115 return newFBO;
2116 }
2117
2118 framebufferIt->second = newFBO;
2119 }
2120
2121 return framebufferIt->second;
2122}
2123
Geoff Lang36167ab2015-12-07 10:27:14 -05002124bool Context::isVertexArrayGenerated(GLuint vertexArray)
2125{
Geoff Langf41a7152016-09-19 15:11:17 -04002126 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002127 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2128}
2129
2130bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2131{
Geoff Langf41a7152016-09-19 15:11:17 -04002132 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002133 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2134}
2135
Shannon Woods53a94a82014-06-24 15:20:36 -04002136void Context::detachTexture(GLuint texture)
2137{
2138 // Simple pass-through to State's detachTexture method, as textures do not require
2139 // allocation map management either here or in the resource manager at detach time.
2140 // Zero textures are held by the Context, and we don't attempt to request them from
2141 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002142 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002143}
2144
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002145void Context::detachBuffer(GLuint buffer)
2146{
Yuly Novikov5807a532015-12-03 13:01:22 -05002147 // Simple pass-through to State's detachBuffer method, since
2148 // only buffer attachments to container objects that are bound to the current context
2149 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002150
Yuly Novikov5807a532015-12-03 13:01:22 -05002151 // [OpenGL ES 3.2] section 5.1.2 page 45:
2152 // Attachments to unbound container objects, such as
2153 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2154 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002155 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002156}
2157
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002158void Context::detachFramebuffer(GLuint framebuffer)
2159{
Shannon Woods53a94a82014-06-24 15:20:36 -04002160 // Framebuffer detachment is handled by Context, because 0 is a valid
2161 // Framebuffer object, and a pointer to it must be passed from Context
2162 // to State at binding time.
2163
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002164 // [OpenGL ES 2.0.24] section 4.4 page 107:
2165 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2166 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2167
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002168 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002169 {
2170 bindReadFramebuffer(0);
2171 }
2172
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002173 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002174 {
2175 bindDrawFramebuffer(0);
2176 }
2177}
2178
2179void Context::detachRenderbuffer(GLuint renderbuffer)
2180{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002181 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002182}
2183
Jamie Madill57a89722013-07-02 11:57:03 -04002184void Context::detachVertexArray(GLuint vertexArray)
2185{
Jamie Madill77a72f62015-04-14 11:18:32 -04002186 // Vertex array detachment is handled by Context, because 0 is a valid
2187 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002188 // binding time.
2189
Jamie Madill57a89722013-07-02 11:57:03 -04002190 // [OpenGL ES 3.0.2] section 2.10 page 43:
2191 // If a vertex array object that is currently bound is deleted, the binding
2192 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002193 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002194 {
2195 bindVertexArray(0);
2196 }
2197}
2198
Geoff Langc8058452014-02-03 12:04:11 -05002199void Context::detachTransformFeedback(GLuint transformFeedback)
2200{
Corentin Walleza2257da2016-04-19 16:43:12 -04002201 // Transform feedback detachment is handled by Context, because 0 is a valid
2202 // transform feedback, and a pointer to it must be passed from Context to State at
2203 // binding time.
2204
2205 // The OpenGL specification doesn't mention what should happen when the currently bound
2206 // transform feedback object is deleted. Since it is a container object, we treat it like
2207 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002208 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002209 {
2210 bindTransformFeedback(0);
2211 }
Geoff Langc8058452014-02-03 12:04:11 -05002212}
2213
Jamie Madilldc356042013-07-19 16:36:57 -04002214void Context::detachSampler(GLuint sampler)
2215{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002216 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002217}
2218
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002219void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2220{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002221 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002222}
2223
Jamie Madille29d1672013-07-19 16:36:57 -04002224void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2225{
Geoff Langc1984ed2016-10-07 12:41:00 -04002226 Sampler *samplerObject =
2227 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2228 SetSamplerParameteri(samplerObject, pname, param);
2229}
Jamie Madille29d1672013-07-19 16:36:57 -04002230
Geoff Langc1984ed2016-10-07 12:41:00 -04002231void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2232{
2233 Sampler *samplerObject =
2234 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2235 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002236}
2237
2238void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2239{
Geoff Langc1984ed2016-10-07 12:41:00 -04002240 Sampler *samplerObject =
2241 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2242 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002243}
2244
Geoff Langc1984ed2016-10-07 12:41:00 -04002245void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002246{
Geoff Langc1984ed2016-10-07 12:41:00 -04002247 Sampler *samplerObject =
2248 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2249 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002250}
2251
Geoff Langc1984ed2016-10-07 12:41:00 -04002252void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002253{
Geoff Langc1984ed2016-10-07 12:41:00 -04002254 const Sampler *samplerObject =
2255 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2256 QuerySamplerParameteriv(samplerObject, pname, params);
2257}
Jamie Madill9675b802013-07-19 16:36:59 -04002258
Geoff Langc1984ed2016-10-07 12:41:00 -04002259void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2260{
2261 const Sampler *samplerObject =
2262 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2263 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002264}
2265
Olli Etuahof0fee072016-03-30 15:11:58 +03002266void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2267{
2268 gl::Program *programObject = getProgram(program);
2269 ASSERT(programObject != nullptr);
2270
2271 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2272 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2273}
2274
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002275void Context::initRendererString()
2276{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002277 std::ostringstream rendererString;
2278 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002279 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002280 rendererString << ")";
2281
Geoff Langcec35902014-04-16 10:52:36 -04002282 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002283}
2284
Geoff Langc339c4e2016-11-29 10:37:36 -05002285void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002286{
Geoff Langc339c4e2016-11-29 10:37:36 -05002287 const Version &clientVersion = getClientVersion();
2288
2289 std::ostringstream versionString;
2290 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2291 << ANGLE_VERSION_STRING << ")";
2292 mVersionString = MakeStaticString(versionString.str());
2293
2294 std::ostringstream shadingLanguageVersionString;
2295 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2296 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2297 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2298 << ")";
2299 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002300}
2301
Geoff Langcec35902014-04-16 10:52:36 -04002302void Context::initExtensionStrings()
2303{
Geoff Langc339c4e2016-11-29 10:37:36 -05002304 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2305 std::ostringstream combinedStringStream;
2306 std::copy(strings.begin(), strings.end(),
2307 std::ostream_iterator<const char *>(combinedStringStream, " "));
2308 return MakeStaticString(combinedStringStream.str());
2309 };
2310
2311 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002312 for (const auto &extensionString : mExtensions.getStrings())
2313 {
2314 mExtensionStrings.push_back(MakeStaticString(extensionString));
2315 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002316 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002317
Geoff Langc339c4e2016-11-29 10:37:36 -05002318 mRequestableExtensionStrings.clear();
2319 for (const auto &extensionInfo : GetExtensionInfoMap())
2320 {
2321 if (extensionInfo.second.Requestable &&
2322 !(mExtensions.*(extensionInfo.second.ExtensionsMember)))
2323 {
2324 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2325 }
2326 }
2327 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002328}
2329
Geoff Langc339c4e2016-11-29 10:37:36 -05002330const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002331{
Geoff Langc339c4e2016-11-29 10:37:36 -05002332 switch (name)
2333 {
2334 case GL_VENDOR:
2335 return reinterpret_cast<const GLubyte *>("Google Inc.");
2336
2337 case GL_RENDERER:
2338 return reinterpret_cast<const GLubyte *>(mRendererString);
2339
2340 case GL_VERSION:
2341 return reinterpret_cast<const GLubyte *>(mVersionString);
2342
2343 case GL_SHADING_LANGUAGE_VERSION:
2344 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2345
2346 case GL_EXTENSIONS:
2347 return reinterpret_cast<const GLubyte *>(mExtensionString);
2348
2349 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2350 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2351
2352 default:
2353 UNREACHABLE();
2354 return nullptr;
2355 }
Geoff Langcec35902014-04-16 10:52:36 -04002356}
2357
Geoff Langc339c4e2016-11-29 10:37:36 -05002358const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002359{
Geoff Langc339c4e2016-11-29 10:37:36 -05002360 switch (name)
2361 {
2362 case GL_EXTENSIONS:
2363 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2364
2365 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2366 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2367
2368 default:
2369 UNREACHABLE();
2370 return nullptr;
2371 }
Geoff Langcec35902014-04-16 10:52:36 -04002372}
2373
2374size_t Context::getExtensionStringCount() const
2375{
2376 return mExtensionStrings.size();
2377}
2378
Geoff Langc339c4e2016-11-29 10:37:36 -05002379void Context::requestExtension(const char *name)
2380{
2381 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2382 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2383 const auto &extension = extensionInfos.at(name);
2384 ASSERT(extension.Requestable);
2385
2386 if (mExtensions.*(extension.ExtensionsMember))
2387 {
2388 // Extension already enabled
2389 return;
2390 }
2391
2392 mExtensions.*(extension.ExtensionsMember) = true;
2393 updateCaps();
2394 initExtensionStrings();
2395}
2396
2397size_t Context::getRequestableExtensionStringCount() const
2398{
2399 return mRequestableExtensionStrings.size();
2400}
2401
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002402void Context::beginTransformFeedback(GLenum primitiveMode)
2403{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002404 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002405 ASSERT(transformFeedback != nullptr);
2406 ASSERT(!transformFeedback->isPaused());
2407
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002408 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002409}
2410
2411bool Context::hasActiveTransformFeedback(GLuint program) const
2412{
2413 for (auto pair : mTransformFeedbackMap)
2414 {
2415 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2416 {
2417 return true;
2418 }
2419 }
2420 return false;
2421}
2422
Geoff Langc287ea62016-09-16 14:46:51 -04002423void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002424{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002425 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002426
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002427 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002428
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002429 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002430
Geoff Langeb66a6e2016-10-31 13:06:12 -04002431 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002432 {
2433 // Disable ES3+ extensions
2434 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002435 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002436 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002437 }
2438
Geoff Langeb66a6e2016-10-31 13:06:12 -04002439 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002440 {
2441 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2442 //mExtensions.sRGB = false;
2443 }
2444
Jamie Madill00ed7a12016-05-19 13:13:38 -04002445 // Some extensions are always available because they are implemented in the GL layer.
2446 mExtensions.bindUniformLocation = true;
2447 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002448 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002449 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002450
2451 // Enable the no error extension if the context was created with the flag.
2452 mExtensions.noError = mSkipValidation;
2453
Geoff Lang70d0f492015-12-10 17:45:46 -05002454 // Explicitly enable GL_KHR_debug
2455 mExtensions.debug = true;
2456 mExtensions.maxDebugMessageLength = 1024;
2457 mExtensions.maxDebugLoggedMessages = 1024;
2458 mExtensions.maxDebugGroupStackDepth = 1024;
2459 mExtensions.maxLabelLength = 1024;
2460
Geoff Langff5b2d52016-09-07 11:32:23 -04002461 // Explicitly enable GL_ANGLE_robust_client_memory
2462 mExtensions.robustClientMemory = true;
2463
Geoff Lang301d1612014-07-09 10:34:37 -04002464 // Apply implementation limits
2465 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002466 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2467 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2468
2469 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002470
Geoff Langc287ea62016-09-16 14:46:51 -04002471 // WebGL compatibility
2472 mExtensions.webglCompatibility = webGLContext;
2473 for (const auto &extensionInfo : GetExtensionInfoMap())
2474 {
2475 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002476 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002477 {
2478 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2479 }
2480 }
2481
2482 // Generate texture caps
2483 updateCaps();
2484}
2485
2486void Context::updateCaps()
2487{
Geoff Lang900013c2014-07-07 11:32:19 -04002488 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002489 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002490
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002491 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002492 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2493 {
2494 GLenum format = i->first;
2495 TextureCaps formatCaps = i->second;
2496
Geoff Lang5d601382014-07-22 15:14:06 -04002497 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002498
Geoff Lang0d8b7242015-09-09 14:56:53 -04002499 // Update the format caps based on the client version and extensions.
2500 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2501 // ES3.
2502 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002503 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002504 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002505 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002506 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002507 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002508
2509 // OpenGL ES does not support multisampling with integer formats
2510 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002511 {
Geoff Langd87878e2014-09-19 15:42:59 -04002512 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002513 }
Geoff Langd87878e2014-09-19 15:42:59 -04002514
2515 if (formatCaps.texturable && formatInfo.compressed)
2516 {
2517 mCaps.compressedTextureFormats.push_back(format);
2518 }
2519
2520 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002521 }
2522}
2523
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002524void Context::initWorkarounds()
2525{
2526 // Lose the context upon out of memory error if the application is
2527 // expecting to watch for those events.
2528 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2529}
2530
Jamie Madill1b94d432015-08-07 13:23:23 -04002531void Context::syncRendererState()
2532{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002533 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2534 mImplementation->syncState(mGLState, dirtyBits);
2535 mGLState.clearDirtyBits();
2536 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002537}
2538
Jamie Madillad9f24e2016-02-12 09:27:24 -05002539void Context::syncRendererState(const State::DirtyBits &bitMask,
2540 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002541{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002542 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2543 mImplementation->syncState(mGLState, dirtyBits);
2544 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002545
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002546 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002547}
Jamie Madillc29968b2016-01-20 11:17:23 -05002548
2549void Context::blitFramebuffer(GLint srcX0,
2550 GLint srcY0,
2551 GLint srcX1,
2552 GLint srcY1,
2553 GLint dstX0,
2554 GLint dstY0,
2555 GLint dstX1,
2556 GLint dstY1,
2557 GLbitfield mask,
2558 GLenum filter)
2559{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002560 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002561 ASSERT(drawFramebuffer);
2562
2563 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2564 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2565
Jamie Madillad9f24e2016-02-12 09:27:24 -05002566 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002567
Jamie Madill8415b5f2016-04-26 13:41:39 -04002568 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002569}
Jamie Madillc29968b2016-01-20 11:17:23 -05002570
2571void Context::clear(GLbitfield mask)
2572{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002573 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002574 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002575}
2576
2577void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2578{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002579 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002580 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2581 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002582}
2583
2584void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2585{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002586 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002587 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2588 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002589}
2590
2591void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2592{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002593 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002594 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2595 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002596}
2597
2598void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2599{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002600 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002601 ASSERT(framebufferObject);
2602
2603 // If a buffer is not present, the clear has no effect
2604 if (framebufferObject->getDepthbuffer() == nullptr &&
2605 framebufferObject->getStencilbuffer() == nullptr)
2606 {
2607 return;
2608 }
2609
Jamie Madillad9f24e2016-02-12 09:27:24 -05002610 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002611 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2612 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002613}
2614
2615void Context::readPixels(GLint x,
2616 GLint y,
2617 GLsizei width,
2618 GLsizei height,
2619 GLenum format,
2620 GLenum type,
2621 GLvoid *pixels)
2622{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002623 if (width == 0 || height == 0)
2624 {
2625 return;
2626 }
2627
Jamie Madillad9f24e2016-02-12 09:27:24 -05002628 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002629
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002630 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002631 ASSERT(framebufferObject);
2632
2633 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002634 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002635}
2636
2637void Context::copyTexImage2D(GLenum target,
2638 GLint level,
2639 GLenum internalformat,
2640 GLint x,
2641 GLint y,
2642 GLsizei width,
2643 GLsizei height,
2644 GLint border)
2645{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002646 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002647 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002648
Jamie Madillc29968b2016-01-20 11:17:23 -05002649 Rectangle sourceArea(x, y, width, height);
2650
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002651 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002652 Texture *texture =
2653 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002654 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002655}
2656
2657void Context::copyTexSubImage2D(GLenum target,
2658 GLint level,
2659 GLint xoffset,
2660 GLint yoffset,
2661 GLint x,
2662 GLint y,
2663 GLsizei width,
2664 GLsizei height)
2665{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002666 if (width == 0 || height == 0)
2667 {
2668 return;
2669 }
2670
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002671 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002672 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002673
Jamie Madillc29968b2016-01-20 11:17:23 -05002674 Offset destOffset(xoffset, yoffset, 0);
2675 Rectangle sourceArea(x, y, width, height);
2676
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002677 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002678 Texture *texture =
2679 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002680 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002681}
2682
2683void Context::copyTexSubImage3D(GLenum target,
2684 GLint level,
2685 GLint xoffset,
2686 GLint yoffset,
2687 GLint zoffset,
2688 GLint x,
2689 GLint y,
2690 GLsizei width,
2691 GLsizei height)
2692{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002693 if (width == 0 || height == 0)
2694 {
2695 return;
2696 }
2697
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002698 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002699 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002700
Jamie Madillc29968b2016-01-20 11:17:23 -05002701 Offset destOffset(xoffset, yoffset, zoffset);
2702 Rectangle sourceArea(x, y, width, height);
2703
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002704 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002705 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002706 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002707}
2708
2709void Context::framebufferTexture2D(GLenum target,
2710 GLenum attachment,
2711 GLenum textarget,
2712 GLuint texture,
2713 GLint level)
2714{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002715 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002716 ASSERT(framebuffer);
2717
2718 if (texture != 0)
2719 {
2720 Texture *textureObj = getTexture(texture);
2721
2722 ImageIndex index = ImageIndex::MakeInvalid();
2723
2724 if (textarget == GL_TEXTURE_2D)
2725 {
2726 index = ImageIndex::Make2D(level);
2727 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002728 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2729 {
2730 ASSERT(level == 0);
2731 index = ImageIndex::Make2DMultisample();
2732 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002733 else
2734 {
2735 ASSERT(IsCubeMapTextureTarget(textarget));
2736 index = ImageIndex::MakeCube(textarget, level);
2737 }
2738
2739 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2740 }
2741 else
2742 {
2743 framebuffer->resetAttachment(attachment);
2744 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002745
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002746 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002747}
2748
2749void Context::framebufferRenderbuffer(GLenum target,
2750 GLenum attachment,
2751 GLenum renderbuffertarget,
2752 GLuint renderbuffer)
2753{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002754 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002755 ASSERT(framebuffer);
2756
2757 if (renderbuffer != 0)
2758 {
2759 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2760 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2761 renderbufferObject);
2762 }
2763 else
2764 {
2765 framebuffer->resetAttachment(attachment);
2766 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002767
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002768 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002769}
2770
2771void Context::framebufferTextureLayer(GLenum target,
2772 GLenum attachment,
2773 GLuint texture,
2774 GLint level,
2775 GLint layer)
2776{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002777 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002778 ASSERT(framebuffer);
2779
2780 if (texture != 0)
2781 {
2782 Texture *textureObject = getTexture(texture);
2783
2784 ImageIndex index = ImageIndex::MakeInvalid();
2785
2786 if (textureObject->getTarget() == GL_TEXTURE_3D)
2787 {
2788 index = ImageIndex::Make3D(level, layer);
2789 }
2790 else
2791 {
2792 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2793 index = ImageIndex::Make2DArray(level, layer);
2794 }
2795
2796 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2797 }
2798 else
2799 {
2800 framebuffer->resetAttachment(attachment);
2801 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002802
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002803 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002804}
2805
2806void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2807{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002808 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002809 ASSERT(framebuffer);
2810 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002811 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002812}
2813
2814void Context::readBuffer(GLenum mode)
2815{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002816 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002817 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002818 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002819}
2820
2821void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2822{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002823 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002824 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002825
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002826 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002827 ASSERT(framebuffer);
2828
2829 // The specification isn't clear what should be done when the framebuffer isn't complete.
2830 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002831 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002832}
2833
2834void Context::invalidateFramebuffer(GLenum target,
2835 GLsizei numAttachments,
2836 const GLenum *attachments)
2837{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002838 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002839 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002840
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002841 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002842 ASSERT(framebuffer);
2843
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002844 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002845 {
Jamie Madill437fa652016-05-03 15:13:24 -04002846 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002847 }
Jamie Madill437fa652016-05-03 15:13:24 -04002848
2849 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002850}
2851
2852void Context::invalidateSubFramebuffer(GLenum target,
2853 GLsizei numAttachments,
2854 const GLenum *attachments,
2855 GLint x,
2856 GLint y,
2857 GLsizei width,
2858 GLsizei height)
2859{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002860 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002861 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002862
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002863 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002864 ASSERT(framebuffer);
2865
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002866 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002867 {
Jamie Madill437fa652016-05-03 15:13:24 -04002868 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002869 }
Jamie Madill437fa652016-05-03 15:13:24 -04002870
2871 Rectangle area(x, y, width, height);
2872 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002873}
2874
Jamie Madill73a84962016-02-12 09:27:23 -05002875void Context::texImage2D(GLenum target,
2876 GLint level,
2877 GLint internalformat,
2878 GLsizei width,
2879 GLsizei height,
2880 GLint border,
2881 GLenum format,
2882 GLenum type,
2883 const GLvoid *pixels)
2884{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002885 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002886
2887 Extents size(width, height, 1);
2888 Texture *texture =
2889 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002890 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002891 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002892}
2893
2894void Context::texImage3D(GLenum target,
2895 GLint level,
2896 GLint internalformat,
2897 GLsizei width,
2898 GLsizei height,
2899 GLsizei depth,
2900 GLint border,
2901 GLenum format,
2902 GLenum type,
2903 const GLvoid *pixels)
2904{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002905 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002906
2907 Extents size(width, height, depth);
2908 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002909 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002910 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002911}
2912
2913void Context::texSubImage2D(GLenum target,
2914 GLint level,
2915 GLint xoffset,
2916 GLint yoffset,
2917 GLsizei width,
2918 GLsizei height,
2919 GLenum format,
2920 GLenum type,
2921 const GLvoid *pixels)
2922{
2923 // Zero sized uploads are valid but no-ops
2924 if (width == 0 || height == 0)
2925 {
2926 return;
2927 }
2928
Jamie Madillad9f24e2016-02-12 09:27:24 -05002929 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002930
2931 Box area(xoffset, yoffset, 0, width, height, 1);
2932 Texture *texture =
2933 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002934 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002935 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002936}
2937
2938void Context::texSubImage3D(GLenum target,
2939 GLint level,
2940 GLint xoffset,
2941 GLint yoffset,
2942 GLint zoffset,
2943 GLsizei width,
2944 GLsizei height,
2945 GLsizei depth,
2946 GLenum format,
2947 GLenum type,
2948 const GLvoid *pixels)
2949{
2950 // Zero sized uploads are valid but no-ops
2951 if (width == 0 || height == 0 || depth == 0)
2952 {
2953 return;
2954 }
2955
Jamie Madillad9f24e2016-02-12 09:27:24 -05002956 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002957
2958 Box area(xoffset, yoffset, zoffset, width, height, depth);
2959 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002960 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002961 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002962}
2963
2964void Context::compressedTexImage2D(GLenum target,
2965 GLint level,
2966 GLenum internalformat,
2967 GLsizei width,
2968 GLsizei height,
2969 GLint border,
2970 GLsizei imageSize,
2971 const GLvoid *data)
2972{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002973 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002974
2975 Extents size(width, height, 1);
2976 Texture *texture =
2977 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002978 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2979 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002980 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002981}
2982
2983void Context::compressedTexImage3D(GLenum target,
2984 GLint level,
2985 GLenum internalformat,
2986 GLsizei width,
2987 GLsizei height,
2988 GLsizei depth,
2989 GLint border,
2990 GLsizei imageSize,
2991 const GLvoid *data)
2992{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002993 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002994
2995 Extents size(width, height, depth);
2996 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002997 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2998 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002999 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003000}
3001
3002void Context::compressedTexSubImage2D(GLenum target,
3003 GLint level,
3004 GLint xoffset,
3005 GLint yoffset,
3006 GLsizei width,
3007 GLsizei height,
3008 GLenum format,
3009 GLsizei imageSize,
3010 const GLvoid *data)
3011{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003012 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003013
3014 Box area(xoffset, yoffset, 0, width, height, 1);
3015 Texture *texture =
3016 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003017 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3018 format, imageSize,
3019 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003020}
3021
3022void Context::compressedTexSubImage3D(GLenum target,
3023 GLint level,
3024 GLint xoffset,
3025 GLint yoffset,
3026 GLint zoffset,
3027 GLsizei width,
3028 GLsizei height,
3029 GLsizei depth,
3030 GLenum format,
3031 GLsizei imageSize,
3032 const GLvoid *data)
3033{
3034 // Zero sized uploads are valid but no-ops
3035 if (width == 0 || height == 0)
3036 {
3037 return;
3038 }
3039
Jamie Madillad9f24e2016-02-12 09:27:24 -05003040 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003041
3042 Box area(xoffset, yoffset, zoffset, width, height, depth);
3043 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003044 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3045 format, imageSize,
3046 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003047}
3048
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003049void Context::generateMipmap(GLenum target)
3050{
3051 Texture *texture = getTargetTexture(target);
3052 handleError(texture->generateMipmap());
3053}
3054
Geoff Lang97073d12016-04-20 10:42:34 -07003055void Context::copyTextureCHROMIUM(GLuint sourceId,
3056 GLuint destId,
3057 GLint internalFormat,
3058 GLenum destType,
3059 GLboolean unpackFlipY,
3060 GLboolean unpackPremultiplyAlpha,
3061 GLboolean unpackUnmultiplyAlpha)
3062{
3063 syncStateForTexImage();
3064
3065 gl::Texture *sourceTexture = getTexture(sourceId);
3066 gl::Texture *destTexture = getTexture(destId);
3067 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3068 unpackPremultiplyAlpha == GL_TRUE,
3069 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3070}
3071
3072void Context::copySubTextureCHROMIUM(GLuint sourceId,
3073 GLuint destId,
3074 GLint xoffset,
3075 GLint yoffset,
3076 GLint x,
3077 GLint y,
3078 GLsizei width,
3079 GLsizei height,
3080 GLboolean unpackFlipY,
3081 GLboolean unpackPremultiplyAlpha,
3082 GLboolean unpackUnmultiplyAlpha)
3083{
3084 // Zero sized copies are valid but no-ops
3085 if (width == 0 || height == 0)
3086 {
3087 return;
3088 }
3089
3090 syncStateForTexImage();
3091
3092 gl::Texture *sourceTexture = getTexture(sourceId);
3093 gl::Texture *destTexture = getTexture(destId);
3094 Offset offset(xoffset, yoffset, 0);
3095 Rectangle area(x, y, width, height);
3096 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3097 unpackPremultiplyAlpha == GL_TRUE,
3098 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3099}
3100
Geoff Lang47110bf2016-04-20 11:13:22 -07003101void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3102{
3103 syncStateForTexImage();
3104
3105 gl::Texture *sourceTexture = getTexture(sourceId);
3106 gl::Texture *destTexture = getTexture(destId);
3107 handleError(destTexture->copyCompressedTexture(sourceTexture));
3108}
3109
Geoff Lang496c02d2016-10-20 11:38:11 -07003110void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003111{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003112 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003113 ASSERT(buffer);
3114
Geoff Lang496c02d2016-10-20 11:38:11 -07003115 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003116}
3117
3118GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3119{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003120 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003121 ASSERT(buffer);
3122
3123 Error error = buffer->map(access);
3124 if (error.isError())
3125 {
Jamie Madill437fa652016-05-03 15:13:24 -04003126 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003127 return nullptr;
3128 }
3129
3130 return buffer->getMapPointer();
3131}
3132
3133GLboolean Context::unmapBuffer(GLenum target)
3134{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003135 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003136 ASSERT(buffer);
3137
3138 GLboolean result;
3139 Error error = buffer->unmap(&result);
3140 if (error.isError())
3141 {
Jamie Madill437fa652016-05-03 15:13:24 -04003142 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003143 return GL_FALSE;
3144 }
3145
3146 return result;
3147}
3148
3149GLvoid *Context::mapBufferRange(GLenum target,
3150 GLintptr offset,
3151 GLsizeiptr length,
3152 GLbitfield access)
3153{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003154 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003155 ASSERT(buffer);
3156
3157 Error error = buffer->mapRange(offset, length, access);
3158 if (error.isError())
3159 {
Jamie Madill437fa652016-05-03 15:13:24 -04003160 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003161 return nullptr;
3162 }
3163
3164 return buffer->getMapPointer();
3165}
3166
3167void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3168{
3169 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3170}
3171
Jamie Madillad9f24e2016-02-12 09:27:24 -05003172void Context::syncStateForReadPixels()
3173{
3174 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3175}
3176
3177void Context::syncStateForTexImage()
3178{
3179 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3180}
3181
3182void Context::syncStateForClear()
3183{
3184 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3185}
3186
3187void Context::syncStateForBlit()
3188{
3189 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3190}
3191
Jamie Madillc20ab272016-06-09 07:20:46 -07003192void Context::activeTexture(GLenum texture)
3193{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003194 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003195}
3196
3197void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3198{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003199 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003200}
3201
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003202void Context::blendEquation(GLenum mode)
3203{
3204 mGLState.setBlendEquation(mode, mode);
3205}
3206
Jamie Madillc20ab272016-06-09 07:20:46 -07003207void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3208{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003209 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003210}
3211
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003212void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3213{
3214 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3215}
3216
Jamie Madillc20ab272016-06-09 07:20:46 -07003217void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3218{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003219 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003220}
3221
3222void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3223{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003224 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003225}
3226
3227void Context::clearDepthf(GLclampf depth)
3228{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003229 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003230}
3231
3232void Context::clearStencil(GLint s)
3233{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003234 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003235}
3236
3237void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3238{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003239 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003240}
3241
3242void Context::cullFace(GLenum mode)
3243{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003244 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003245}
3246
3247void Context::depthFunc(GLenum func)
3248{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003249 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003250}
3251
3252void Context::depthMask(GLboolean flag)
3253{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003254 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003255}
3256
3257void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3258{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003259 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003260}
3261
3262void Context::disable(GLenum cap)
3263{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003264 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003265}
3266
3267void Context::disableVertexAttribArray(GLuint index)
3268{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003269 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003270}
3271
3272void Context::enable(GLenum cap)
3273{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003274 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003275}
3276
3277void Context::enableVertexAttribArray(GLuint index)
3278{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003279 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003280}
3281
3282void Context::frontFace(GLenum mode)
3283{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003284 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003285}
3286
3287void Context::hint(GLenum target, GLenum mode)
3288{
3289 switch (target)
3290 {
3291 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003292 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003293 break;
3294
3295 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003297 break;
3298
3299 default:
3300 UNREACHABLE();
3301 return;
3302 }
3303}
3304
3305void Context::lineWidth(GLfloat width)
3306{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003307 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003308}
3309
3310void Context::pixelStorei(GLenum pname, GLint param)
3311{
3312 switch (pname)
3313 {
3314 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003315 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003316 break;
3317
3318 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003319 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003320 break;
3321
3322 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003323 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003324 break;
3325
3326 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003327 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003328 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003329 break;
3330
3331 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003332 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003333 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003334 break;
3335
3336 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003337 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003338 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003339 break;
3340
3341 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003342 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003343 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003344 break;
3345
3346 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003347 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003348 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003349 break;
3350
3351 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003352 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003353 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003354 break;
3355
3356 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003357 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003358 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003359 break;
3360
3361 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003362 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003363 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003364 break;
3365
3366 default:
3367 UNREACHABLE();
3368 return;
3369 }
3370}
3371
3372void Context::polygonOffset(GLfloat factor, GLfloat units)
3373{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003374 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003375}
3376
3377void Context::sampleCoverage(GLclampf value, GLboolean invert)
3378{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003379 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003380}
3381
3382void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3383{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003384 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003385}
3386
3387void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3388{
3389 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3390 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003391 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003392 }
3393
3394 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3395 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003396 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003397 }
3398}
3399
3400void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3401{
3402 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3403 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003404 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003405 }
3406
3407 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3408 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003409 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003410 }
3411}
3412
3413void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3414{
3415 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3416 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003417 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003418 }
3419
3420 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3421 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003422 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003423 }
3424}
3425
3426void Context::vertexAttrib1f(GLuint index, GLfloat x)
3427{
3428 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003429 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003430}
3431
3432void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3433{
3434 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003435 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003436}
3437
3438void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3439{
3440 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003441 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003442}
3443
3444void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3445{
3446 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003447 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003448}
3449
3450void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3451{
3452 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003453 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003454}
3455
3456void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3457{
3458 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003460}
3461
3462void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3463{
3464 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003466}
3467
3468void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3469{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003470 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003471}
3472
3473void Context::vertexAttribPointer(GLuint index,
3474 GLint size,
3475 GLenum type,
3476 GLboolean normalized,
3477 GLsizei stride,
3478 const GLvoid *ptr)
3479{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003480 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3481 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003482}
3483
3484void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3485{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003486 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003487}
3488
3489void Context::vertexAttribIPointer(GLuint index,
3490 GLint size,
3491 GLenum type,
3492 GLsizei stride,
3493 const GLvoid *pointer)
3494{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003495 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3496 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003497}
3498
3499void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3500{
3501 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003502 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003503}
3504
3505void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3506{
3507 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003509}
3510
3511void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3512{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003513 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003514}
3515
3516void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3517{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003518 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003519}
3520
3521void Context::debugMessageControl(GLenum source,
3522 GLenum type,
3523 GLenum severity,
3524 GLsizei count,
3525 const GLuint *ids,
3526 GLboolean enabled)
3527{
3528 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3530 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003531}
3532
3533void Context::debugMessageInsert(GLenum source,
3534 GLenum type,
3535 GLuint id,
3536 GLenum severity,
3537 GLsizei length,
3538 const GLchar *buf)
3539{
3540 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003541 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003542}
3543
3544void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3545{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003546 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003547}
3548
3549GLuint Context::getDebugMessageLog(GLuint count,
3550 GLsizei bufSize,
3551 GLenum *sources,
3552 GLenum *types,
3553 GLuint *ids,
3554 GLenum *severities,
3555 GLsizei *lengths,
3556 GLchar *messageLog)
3557{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003558 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3559 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003560}
3561
3562void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3563{
3564 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003565 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003566}
3567
3568void Context::popDebugGroup()
3569{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003570 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003571}
3572
Jamie Madill29639852016-09-02 15:00:09 -04003573void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3574{
3575 Buffer *buffer = mGLState.getTargetBuffer(target);
3576 ASSERT(buffer);
3577 handleError(buffer->bufferData(target, data, size, usage));
3578}
3579
3580void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3581{
3582 if (data == nullptr)
3583 {
3584 return;
3585 }
3586
3587 Buffer *buffer = mGLState.getTargetBuffer(target);
3588 ASSERT(buffer);
3589 handleError(buffer->bufferSubData(target, data, size, offset));
3590}
3591
Jamie Madillef300b12016-10-07 15:12:09 -04003592void Context::attachShader(GLuint program, GLuint shader)
3593{
3594 auto programObject = mResourceManager->getProgram(program);
3595 auto shaderObject = mResourceManager->getShader(shader);
3596 ASSERT(programObject && shaderObject);
3597 programObject->attachShader(shaderObject);
3598}
3599
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003600const Workarounds &Context::getWorkarounds() const
3601{
3602 return mWorkarounds;
3603}
3604
Jamie Madillb0817d12016-11-01 15:48:31 -04003605void Context::copyBufferSubData(GLenum readTarget,
3606 GLenum writeTarget,
3607 GLintptr readOffset,
3608 GLintptr writeOffset,
3609 GLsizeiptr size)
3610{
3611 // if size is zero, the copy is a successful no-op
3612 if (size == 0)
3613 {
3614 return;
3615 }
3616
3617 // TODO(jmadill): cache these.
3618 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3619 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3620
3621 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3622}
3623
Jamie Madill01a80ee2016-11-07 12:06:18 -05003624void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3625{
3626 Program *programObject = getProgram(program);
3627 // TODO(jmadill): Re-use this from the validation if possible.
3628 ASSERT(programObject);
3629 programObject->bindAttributeLocation(index, name);
3630}
3631
3632void Context::bindBuffer(GLenum target, GLuint buffer)
3633{
3634 switch (target)
3635 {
3636 case GL_ARRAY_BUFFER:
3637 bindArrayBuffer(buffer);
3638 break;
3639 case GL_ELEMENT_ARRAY_BUFFER:
3640 bindElementArrayBuffer(buffer);
3641 break;
3642 case GL_COPY_READ_BUFFER:
3643 bindCopyReadBuffer(buffer);
3644 break;
3645 case GL_COPY_WRITE_BUFFER:
3646 bindCopyWriteBuffer(buffer);
3647 break;
3648 case GL_PIXEL_PACK_BUFFER:
3649 bindPixelPackBuffer(buffer);
3650 break;
3651 case GL_PIXEL_UNPACK_BUFFER:
3652 bindPixelUnpackBuffer(buffer);
3653 break;
3654 case GL_UNIFORM_BUFFER:
3655 bindGenericUniformBuffer(buffer);
3656 break;
3657 case GL_TRANSFORM_FEEDBACK_BUFFER:
3658 bindGenericTransformFeedbackBuffer(buffer);
3659 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003660 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003661 if (buffer != 0)
3662 {
3663 // Binding buffers to this binding point is not implemented yet.
3664 UNIMPLEMENTED();
3665 }
Geoff Lang3b573612016-10-31 14:08:10 -04003666 break;
3667 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003668 if (buffer != 0)
3669 {
3670 // Binding buffers to this binding point is not implemented yet.
3671 UNIMPLEMENTED();
3672 }
Geoff Lang3b573612016-10-31 14:08:10 -04003673 break;
3674 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003675 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003676 break;
3677 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003678 if (buffer != 0)
3679 {
3680 // Binding buffers to this binding point is not implemented yet.
3681 UNIMPLEMENTED();
3682 }
Geoff Lang3b573612016-10-31 14:08:10 -04003683 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003684
3685 default:
3686 UNREACHABLE();
3687 break;
3688 }
3689}
3690
3691void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3692{
3693 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3694 {
3695 bindReadFramebuffer(framebuffer);
3696 }
3697
3698 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3699 {
3700 bindDrawFramebuffer(framebuffer);
3701 }
3702}
3703
3704void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3705{
3706 ASSERT(target == GL_RENDERBUFFER);
3707 Renderbuffer *object =
3708 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
3709 mGLState.setRenderbufferBinding(object);
3710}
3711
JiangYizhoubddc46b2016-12-09 09:50:51 +08003712void Context::texStorage2DMultisample(GLenum target,
3713 GLsizei samples,
3714 GLenum internalformat,
3715 GLsizei width,
3716 GLsizei height,
3717 GLboolean fixedsamplelocations)
3718{
3719 Extents size(width, height, 1);
3720 Texture *texture = getTargetTexture(target);
3721 handleError(texture->setStorageMultisample(target, samples, internalformat, size,
3722 fixedsamplelocations));
3723}
3724
3725void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3726{
3727 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3728 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3729
3730 switch (pname)
3731 {
3732 case GL_SAMPLE_POSITION:
3733 handleError(framebuffer->getSamplePosition(index, val));
3734 break;
3735 default:
3736 UNREACHABLE();
3737 }
3738}
3739
Jamie Madillc29968b2016-01-20 11:17:23 -05003740} // namespace gl