blob: fa1a31961f39f53333ccb3d6c0cf9b503e1163cf [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
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002509 // OpenGL ES does not support multisampling with non-rendererable formats
2510 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2511 if (!formatInfo.renderSupport ||
2512 (getClientVersion() < ES_3_1 &&
2513 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002514 {
Geoff Langd87878e2014-09-19 15:42:59 -04002515 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002516 }
Geoff Langd87878e2014-09-19 15:42:59 -04002517
2518 if (formatCaps.texturable && formatInfo.compressed)
2519 {
2520 mCaps.compressedTextureFormats.push_back(format);
2521 }
2522
2523 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002524 }
2525}
2526
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002527void Context::initWorkarounds()
2528{
2529 // Lose the context upon out of memory error if the application is
2530 // expecting to watch for those events.
2531 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2532}
2533
Jamie Madill1b94d432015-08-07 13:23:23 -04002534void Context::syncRendererState()
2535{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002536 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2537 mImplementation->syncState(mGLState, dirtyBits);
2538 mGLState.clearDirtyBits();
2539 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002540}
2541
Jamie Madillad9f24e2016-02-12 09:27:24 -05002542void Context::syncRendererState(const State::DirtyBits &bitMask,
2543 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002544{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002545 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2546 mImplementation->syncState(mGLState, dirtyBits);
2547 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002548
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002549 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002550}
Jamie Madillc29968b2016-01-20 11:17:23 -05002551
2552void Context::blitFramebuffer(GLint srcX0,
2553 GLint srcY0,
2554 GLint srcX1,
2555 GLint srcY1,
2556 GLint dstX0,
2557 GLint dstY0,
2558 GLint dstX1,
2559 GLint dstY1,
2560 GLbitfield mask,
2561 GLenum filter)
2562{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002563 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002564 ASSERT(drawFramebuffer);
2565
2566 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2567 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2568
Jamie Madillad9f24e2016-02-12 09:27:24 -05002569 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002570
Jamie Madill8415b5f2016-04-26 13:41:39 -04002571 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002572}
Jamie Madillc29968b2016-01-20 11:17:23 -05002573
2574void Context::clear(GLbitfield mask)
2575{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002576 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002577 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002578}
2579
2580void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2581{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002582 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002583 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2584 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002585}
2586
2587void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2588{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002589 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002590 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2591 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002592}
2593
2594void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2595{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002596 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002597 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2598 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002599}
2600
2601void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2602{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002603 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002604 ASSERT(framebufferObject);
2605
2606 // If a buffer is not present, the clear has no effect
2607 if (framebufferObject->getDepthbuffer() == nullptr &&
2608 framebufferObject->getStencilbuffer() == nullptr)
2609 {
2610 return;
2611 }
2612
Jamie Madillad9f24e2016-02-12 09:27:24 -05002613 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002614 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2615 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002616}
2617
2618void Context::readPixels(GLint x,
2619 GLint y,
2620 GLsizei width,
2621 GLsizei height,
2622 GLenum format,
2623 GLenum type,
2624 GLvoid *pixels)
2625{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002626 if (width == 0 || height == 0)
2627 {
2628 return;
2629 }
2630
Jamie Madillad9f24e2016-02-12 09:27:24 -05002631 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002632
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002633 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002634 ASSERT(framebufferObject);
2635
2636 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002637 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002638}
2639
2640void Context::copyTexImage2D(GLenum target,
2641 GLint level,
2642 GLenum internalformat,
2643 GLint x,
2644 GLint y,
2645 GLsizei width,
2646 GLsizei height,
2647 GLint border)
2648{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002649 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002650 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002651
Jamie Madillc29968b2016-01-20 11:17:23 -05002652 Rectangle sourceArea(x, y, width, height);
2653
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002654 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002655 Texture *texture =
2656 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002657 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002658}
2659
2660void Context::copyTexSubImage2D(GLenum target,
2661 GLint level,
2662 GLint xoffset,
2663 GLint yoffset,
2664 GLint x,
2665 GLint y,
2666 GLsizei width,
2667 GLsizei height)
2668{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002669 if (width == 0 || height == 0)
2670 {
2671 return;
2672 }
2673
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002674 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002675 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002676
Jamie Madillc29968b2016-01-20 11:17:23 -05002677 Offset destOffset(xoffset, yoffset, 0);
2678 Rectangle sourceArea(x, y, width, height);
2679
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002680 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002681 Texture *texture =
2682 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002683 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002684}
2685
2686void Context::copyTexSubImage3D(GLenum target,
2687 GLint level,
2688 GLint xoffset,
2689 GLint yoffset,
2690 GLint zoffset,
2691 GLint x,
2692 GLint y,
2693 GLsizei width,
2694 GLsizei height)
2695{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002696 if (width == 0 || height == 0)
2697 {
2698 return;
2699 }
2700
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002701 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002702 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002703
Jamie Madillc29968b2016-01-20 11:17:23 -05002704 Offset destOffset(xoffset, yoffset, zoffset);
2705 Rectangle sourceArea(x, y, width, height);
2706
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002707 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002708 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002709 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002710}
2711
2712void Context::framebufferTexture2D(GLenum target,
2713 GLenum attachment,
2714 GLenum textarget,
2715 GLuint texture,
2716 GLint level)
2717{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002718 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002719 ASSERT(framebuffer);
2720
2721 if (texture != 0)
2722 {
2723 Texture *textureObj = getTexture(texture);
2724
2725 ImageIndex index = ImageIndex::MakeInvalid();
2726
2727 if (textarget == GL_TEXTURE_2D)
2728 {
2729 index = ImageIndex::Make2D(level);
2730 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002731 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2732 {
2733 ASSERT(level == 0);
2734 index = ImageIndex::Make2DMultisample();
2735 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002736 else
2737 {
2738 ASSERT(IsCubeMapTextureTarget(textarget));
2739 index = ImageIndex::MakeCube(textarget, level);
2740 }
2741
2742 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2743 }
2744 else
2745 {
2746 framebuffer->resetAttachment(attachment);
2747 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002748
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002749 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002750}
2751
2752void Context::framebufferRenderbuffer(GLenum target,
2753 GLenum attachment,
2754 GLenum renderbuffertarget,
2755 GLuint renderbuffer)
2756{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002757 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002758 ASSERT(framebuffer);
2759
2760 if (renderbuffer != 0)
2761 {
2762 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2763 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2764 renderbufferObject);
2765 }
2766 else
2767 {
2768 framebuffer->resetAttachment(attachment);
2769 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002770
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002771 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002772}
2773
2774void Context::framebufferTextureLayer(GLenum target,
2775 GLenum attachment,
2776 GLuint texture,
2777 GLint level,
2778 GLint layer)
2779{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002780 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002781 ASSERT(framebuffer);
2782
2783 if (texture != 0)
2784 {
2785 Texture *textureObject = getTexture(texture);
2786
2787 ImageIndex index = ImageIndex::MakeInvalid();
2788
2789 if (textureObject->getTarget() == GL_TEXTURE_3D)
2790 {
2791 index = ImageIndex::Make3D(level, layer);
2792 }
2793 else
2794 {
2795 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2796 index = ImageIndex::Make2DArray(level, layer);
2797 }
2798
2799 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2800 }
2801 else
2802 {
2803 framebuffer->resetAttachment(attachment);
2804 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002805
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002806 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002807}
2808
2809void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2810{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002811 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002812 ASSERT(framebuffer);
2813 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002814 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002815}
2816
2817void Context::readBuffer(GLenum mode)
2818{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002820 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002821 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002822}
2823
2824void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2825{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002826 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002827 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002828
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002829 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002830 ASSERT(framebuffer);
2831
2832 // The specification isn't clear what should be done when the framebuffer isn't complete.
2833 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002834 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002835}
2836
2837void Context::invalidateFramebuffer(GLenum target,
2838 GLsizei numAttachments,
2839 const GLenum *attachments)
2840{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002841 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002842 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002843
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002844 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002845 ASSERT(framebuffer);
2846
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002847 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002848 {
Jamie Madill437fa652016-05-03 15:13:24 -04002849 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002850 }
Jamie Madill437fa652016-05-03 15:13:24 -04002851
2852 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002853}
2854
2855void Context::invalidateSubFramebuffer(GLenum target,
2856 GLsizei numAttachments,
2857 const GLenum *attachments,
2858 GLint x,
2859 GLint y,
2860 GLsizei width,
2861 GLsizei height)
2862{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002863 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002864 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002865
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002866 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002867 ASSERT(framebuffer);
2868
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002869 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002870 {
Jamie Madill437fa652016-05-03 15:13:24 -04002871 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002872 }
Jamie Madill437fa652016-05-03 15:13:24 -04002873
2874 Rectangle area(x, y, width, height);
2875 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002876}
2877
Jamie Madill73a84962016-02-12 09:27:23 -05002878void Context::texImage2D(GLenum target,
2879 GLint level,
2880 GLint internalformat,
2881 GLsizei width,
2882 GLsizei height,
2883 GLint border,
2884 GLenum format,
2885 GLenum type,
2886 const GLvoid *pixels)
2887{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002888 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002889
2890 Extents size(width, height, 1);
2891 Texture *texture =
2892 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002893 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002894 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002895}
2896
2897void Context::texImage3D(GLenum target,
2898 GLint level,
2899 GLint internalformat,
2900 GLsizei width,
2901 GLsizei height,
2902 GLsizei depth,
2903 GLint border,
2904 GLenum format,
2905 GLenum type,
2906 const GLvoid *pixels)
2907{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002908 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002909
2910 Extents size(width, height, depth);
2911 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002912 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002913 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002914}
2915
2916void Context::texSubImage2D(GLenum target,
2917 GLint level,
2918 GLint xoffset,
2919 GLint yoffset,
2920 GLsizei width,
2921 GLsizei height,
2922 GLenum format,
2923 GLenum type,
2924 const GLvoid *pixels)
2925{
2926 // Zero sized uploads are valid but no-ops
2927 if (width == 0 || height == 0)
2928 {
2929 return;
2930 }
2931
Jamie Madillad9f24e2016-02-12 09:27:24 -05002932 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002933
2934 Box area(xoffset, yoffset, 0, width, height, 1);
2935 Texture *texture =
2936 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002937 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002938 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002939}
2940
2941void Context::texSubImage3D(GLenum target,
2942 GLint level,
2943 GLint xoffset,
2944 GLint yoffset,
2945 GLint zoffset,
2946 GLsizei width,
2947 GLsizei height,
2948 GLsizei depth,
2949 GLenum format,
2950 GLenum type,
2951 const GLvoid *pixels)
2952{
2953 // Zero sized uploads are valid but no-ops
2954 if (width == 0 || height == 0 || depth == 0)
2955 {
2956 return;
2957 }
2958
Jamie Madillad9f24e2016-02-12 09:27:24 -05002959 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002960
2961 Box area(xoffset, yoffset, zoffset, width, height, depth);
2962 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002963 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002964 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002965}
2966
2967void Context::compressedTexImage2D(GLenum target,
2968 GLint level,
2969 GLenum internalformat,
2970 GLsizei width,
2971 GLsizei height,
2972 GLint border,
2973 GLsizei imageSize,
2974 const GLvoid *data)
2975{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002976 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002977
2978 Extents size(width, height, 1);
2979 Texture *texture =
2980 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002981 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2982 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002983 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002984}
2985
2986void Context::compressedTexImage3D(GLenum target,
2987 GLint level,
2988 GLenum internalformat,
2989 GLsizei width,
2990 GLsizei height,
2991 GLsizei depth,
2992 GLint border,
2993 GLsizei imageSize,
2994 const GLvoid *data)
2995{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002996 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002997
2998 Extents size(width, height, depth);
2999 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003000 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
3001 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003002 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003003}
3004
3005void Context::compressedTexSubImage2D(GLenum target,
3006 GLint level,
3007 GLint xoffset,
3008 GLint yoffset,
3009 GLsizei width,
3010 GLsizei height,
3011 GLenum format,
3012 GLsizei imageSize,
3013 const GLvoid *data)
3014{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003015 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003016
3017 Box area(xoffset, yoffset, 0, width, height, 1);
3018 Texture *texture =
3019 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003020 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3021 format, imageSize,
3022 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003023}
3024
3025void Context::compressedTexSubImage3D(GLenum target,
3026 GLint level,
3027 GLint xoffset,
3028 GLint yoffset,
3029 GLint zoffset,
3030 GLsizei width,
3031 GLsizei height,
3032 GLsizei depth,
3033 GLenum format,
3034 GLsizei imageSize,
3035 const GLvoid *data)
3036{
3037 // Zero sized uploads are valid but no-ops
3038 if (width == 0 || height == 0)
3039 {
3040 return;
3041 }
3042
Jamie Madillad9f24e2016-02-12 09:27:24 -05003043 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003044
3045 Box area(xoffset, yoffset, zoffset, width, height, depth);
3046 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003047 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3048 format, imageSize,
3049 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003050}
3051
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003052void Context::generateMipmap(GLenum target)
3053{
3054 Texture *texture = getTargetTexture(target);
3055 handleError(texture->generateMipmap());
3056}
3057
Geoff Lang97073d12016-04-20 10:42:34 -07003058void Context::copyTextureCHROMIUM(GLuint sourceId,
3059 GLuint destId,
3060 GLint internalFormat,
3061 GLenum destType,
3062 GLboolean unpackFlipY,
3063 GLboolean unpackPremultiplyAlpha,
3064 GLboolean unpackUnmultiplyAlpha)
3065{
3066 syncStateForTexImage();
3067
3068 gl::Texture *sourceTexture = getTexture(sourceId);
3069 gl::Texture *destTexture = getTexture(destId);
3070 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3071 unpackPremultiplyAlpha == GL_TRUE,
3072 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3073}
3074
3075void Context::copySubTextureCHROMIUM(GLuint sourceId,
3076 GLuint destId,
3077 GLint xoffset,
3078 GLint yoffset,
3079 GLint x,
3080 GLint y,
3081 GLsizei width,
3082 GLsizei height,
3083 GLboolean unpackFlipY,
3084 GLboolean unpackPremultiplyAlpha,
3085 GLboolean unpackUnmultiplyAlpha)
3086{
3087 // Zero sized copies are valid but no-ops
3088 if (width == 0 || height == 0)
3089 {
3090 return;
3091 }
3092
3093 syncStateForTexImage();
3094
3095 gl::Texture *sourceTexture = getTexture(sourceId);
3096 gl::Texture *destTexture = getTexture(destId);
3097 Offset offset(xoffset, yoffset, 0);
3098 Rectangle area(x, y, width, height);
3099 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3100 unpackPremultiplyAlpha == GL_TRUE,
3101 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3102}
3103
Geoff Lang47110bf2016-04-20 11:13:22 -07003104void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3105{
3106 syncStateForTexImage();
3107
3108 gl::Texture *sourceTexture = getTexture(sourceId);
3109 gl::Texture *destTexture = getTexture(destId);
3110 handleError(destTexture->copyCompressedTexture(sourceTexture));
3111}
3112
Geoff Lang496c02d2016-10-20 11:38:11 -07003113void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003114{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003115 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003116 ASSERT(buffer);
3117
Geoff Lang496c02d2016-10-20 11:38:11 -07003118 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003119}
3120
3121GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3122{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003123 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003124 ASSERT(buffer);
3125
3126 Error error = buffer->map(access);
3127 if (error.isError())
3128 {
Jamie Madill437fa652016-05-03 15:13:24 -04003129 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003130 return nullptr;
3131 }
3132
3133 return buffer->getMapPointer();
3134}
3135
3136GLboolean Context::unmapBuffer(GLenum target)
3137{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003138 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003139 ASSERT(buffer);
3140
3141 GLboolean result;
3142 Error error = buffer->unmap(&result);
3143 if (error.isError())
3144 {
Jamie Madill437fa652016-05-03 15:13:24 -04003145 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003146 return GL_FALSE;
3147 }
3148
3149 return result;
3150}
3151
3152GLvoid *Context::mapBufferRange(GLenum target,
3153 GLintptr offset,
3154 GLsizeiptr length,
3155 GLbitfield access)
3156{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003157 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003158 ASSERT(buffer);
3159
3160 Error error = buffer->mapRange(offset, length, access);
3161 if (error.isError())
3162 {
Jamie Madill437fa652016-05-03 15:13:24 -04003163 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003164 return nullptr;
3165 }
3166
3167 return buffer->getMapPointer();
3168}
3169
3170void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3171{
3172 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3173}
3174
Jamie Madillad9f24e2016-02-12 09:27:24 -05003175void Context::syncStateForReadPixels()
3176{
3177 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3178}
3179
3180void Context::syncStateForTexImage()
3181{
3182 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3183}
3184
3185void Context::syncStateForClear()
3186{
3187 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3188}
3189
3190void Context::syncStateForBlit()
3191{
3192 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3193}
3194
Jamie Madillc20ab272016-06-09 07:20:46 -07003195void Context::activeTexture(GLenum texture)
3196{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003197 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003198}
3199
3200void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3201{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003202 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003203}
3204
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003205void Context::blendEquation(GLenum mode)
3206{
3207 mGLState.setBlendEquation(mode, mode);
3208}
3209
Jamie Madillc20ab272016-06-09 07:20:46 -07003210void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003212 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003213}
3214
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003215void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3216{
3217 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3218}
3219
Jamie Madillc20ab272016-06-09 07:20:46 -07003220void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3221{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003222 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003223}
3224
3225void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3226{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003227 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003228}
3229
3230void Context::clearDepthf(GLclampf depth)
3231{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003232 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003233}
3234
3235void Context::clearStencil(GLint s)
3236{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003237 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003238}
3239
3240void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3241{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003242 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003243}
3244
3245void Context::cullFace(GLenum mode)
3246{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003247 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003248}
3249
3250void Context::depthFunc(GLenum func)
3251{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003252 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003253}
3254
3255void Context::depthMask(GLboolean flag)
3256{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003257 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003258}
3259
3260void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3261{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003262 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003263}
3264
3265void Context::disable(GLenum cap)
3266{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003267 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003268}
3269
3270void Context::disableVertexAttribArray(GLuint index)
3271{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003272 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003273}
3274
3275void Context::enable(GLenum cap)
3276{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003277 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003278}
3279
3280void Context::enableVertexAttribArray(GLuint index)
3281{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003282 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003283}
3284
3285void Context::frontFace(GLenum mode)
3286{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003287 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003288}
3289
3290void Context::hint(GLenum target, GLenum mode)
3291{
3292 switch (target)
3293 {
3294 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003295 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003296 break;
3297
3298 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003299 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003300 break;
3301
3302 default:
3303 UNREACHABLE();
3304 return;
3305 }
3306}
3307
3308void Context::lineWidth(GLfloat width)
3309{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003310 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003311}
3312
3313void Context::pixelStorei(GLenum pname, GLint param)
3314{
3315 switch (pname)
3316 {
3317 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003318 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003319 break;
3320
3321 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003322 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003323 break;
3324
3325 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003326 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003327 break;
3328
3329 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003330 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003331 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003332 break;
3333
3334 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003335 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003336 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003337 break;
3338
3339 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003340 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003341 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003342 break;
3343
3344 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003345 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003346 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003347 break;
3348
3349 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003350 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003351 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003352 break;
3353
3354 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003355 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003356 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003357 break;
3358
3359 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003360 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003361 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003362 break;
3363
3364 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003365 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003366 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003367 break;
3368
3369 default:
3370 UNREACHABLE();
3371 return;
3372 }
3373}
3374
3375void Context::polygonOffset(GLfloat factor, GLfloat units)
3376{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003377 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003378}
3379
3380void Context::sampleCoverage(GLclampf value, GLboolean invert)
3381{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003382 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003383}
3384
3385void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3386{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003387 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003388}
3389
3390void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3391{
3392 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3393 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003394 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003395 }
3396
3397 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3398 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003400 }
3401}
3402
3403void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3404{
3405 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3406 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003407 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003408 }
3409
3410 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3411 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003412 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003413 }
3414}
3415
3416void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3417{
3418 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3419 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003420 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003421 }
3422
3423 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3424 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003425 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003426 }
3427}
3428
3429void Context::vertexAttrib1f(GLuint index, GLfloat x)
3430{
3431 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003432 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003433}
3434
3435void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3436{
3437 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003438 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003439}
3440
3441void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3442{
3443 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003444 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003445}
3446
3447void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3448{
3449 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003450 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003451}
3452
3453void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3454{
3455 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003456 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003457}
3458
3459void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3460{
3461 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003462 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003463}
3464
3465void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3466{
3467 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003468 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003469}
3470
3471void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3472{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003473 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003474}
3475
3476void Context::vertexAttribPointer(GLuint index,
3477 GLint size,
3478 GLenum type,
3479 GLboolean normalized,
3480 GLsizei stride,
3481 const GLvoid *ptr)
3482{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3484 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003485}
3486
3487void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3488{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003489 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003490}
3491
3492void Context::vertexAttribIPointer(GLuint index,
3493 GLint size,
3494 GLenum type,
3495 GLsizei stride,
3496 const GLvoid *pointer)
3497{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003498 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3499 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003500}
3501
3502void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3503{
3504 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003505 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003506}
3507
3508void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3509{
3510 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003511 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003512}
3513
3514void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3515{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003516 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003517}
3518
3519void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3520{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003521 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003522}
3523
3524void Context::debugMessageControl(GLenum source,
3525 GLenum type,
3526 GLenum severity,
3527 GLsizei count,
3528 const GLuint *ids,
3529 GLboolean enabled)
3530{
3531 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003532 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3533 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003534}
3535
3536void Context::debugMessageInsert(GLenum source,
3537 GLenum type,
3538 GLuint id,
3539 GLenum severity,
3540 GLsizei length,
3541 const GLchar *buf)
3542{
3543 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003545}
3546
3547void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003550}
3551
3552GLuint Context::getDebugMessageLog(GLuint count,
3553 GLsizei bufSize,
3554 GLenum *sources,
3555 GLenum *types,
3556 GLuint *ids,
3557 GLenum *severities,
3558 GLsizei *lengths,
3559 GLchar *messageLog)
3560{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003561 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3562 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003563}
3564
3565void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3566{
3567 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003568 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003569}
3570
3571void Context::popDebugGroup()
3572{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003573 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003574}
3575
Jamie Madill29639852016-09-02 15:00:09 -04003576void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3577{
3578 Buffer *buffer = mGLState.getTargetBuffer(target);
3579 ASSERT(buffer);
3580 handleError(buffer->bufferData(target, data, size, usage));
3581}
3582
3583void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3584{
3585 if (data == nullptr)
3586 {
3587 return;
3588 }
3589
3590 Buffer *buffer = mGLState.getTargetBuffer(target);
3591 ASSERT(buffer);
3592 handleError(buffer->bufferSubData(target, data, size, offset));
3593}
3594
Jamie Madillef300b12016-10-07 15:12:09 -04003595void Context::attachShader(GLuint program, GLuint shader)
3596{
3597 auto programObject = mResourceManager->getProgram(program);
3598 auto shaderObject = mResourceManager->getShader(shader);
3599 ASSERT(programObject && shaderObject);
3600 programObject->attachShader(shaderObject);
3601}
3602
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003603const Workarounds &Context::getWorkarounds() const
3604{
3605 return mWorkarounds;
3606}
3607
Jamie Madillb0817d12016-11-01 15:48:31 -04003608void Context::copyBufferSubData(GLenum readTarget,
3609 GLenum writeTarget,
3610 GLintptr readOffset,
3611 GLintptr writeOffset,
3612 GLsizeiptr size)
3613{
3614 // if size is zero, the copy is a successful no-op
3615 if (size == 0)
3616 {
3617 return;
3618 }
3619
3620 // TODO(jmadill): cache these.
3621 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3622 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3623
3624 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3625}
3626
Jamie Madill01a80ee2016-11-07 12:06:18 -05003627void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3628{
3629 Program *programObject = getProgram(program);
3630 // TODO(jmadill): Re-use this from the validation if possible.
3631 ASSERT(programObject);
3632 programObject->bindAttributeLocation(index, name);
3633}
3634
3635void Context::bindBuffer(GLenum target, GLuint buffer)
3636{
3637 switch (target)
3638 {
3639 case GL_ARRAY_BUFFER:
3640 bindArrayBuffer(buffer);
3641 break;
3642 case GL_ELEMENT_ARRAY_BUFFER:
3643 bindElementArrayBuffer(buffer);
3644 break;
3645 case GL_COPY_READ_BUFFER:
3646 bindCopyReadBuffer(buffer);
3647 break;
3648 case GL_COPY_WRITE_BUFFER:
3649 bindCopyWriteBuffer(buffer);
3650 break;
3651 case GL_PIXEL_PACK_BUFFER:
3652 bindPixelPackBuffer(buffer);
3653 break;
3654 case GL_PIXEL_UNPACK_BUFFER:
3655 bindPixelUnpackBuffer(buffer);
3656 break;
3657 case GL_UNIFORM_BUFFER:
3658 bindGenericUniformBuffer(buffer);
3659 break;
3660 case GL_TRANSFORM_FEEDBACK_BUFFER:
3661 bindGenericTransformFeedbackBuffer(buffer);
3662 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003663 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003664 if (buffer != 0)
3665 {
3666 // Binding buffers to this binding point is not implemented yet.
3667 UNIMPLEMENTED();
3668 }
Geoff Lang3b573612016-10-31 14:08:10 -04003669 break;
3670 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003671 if (buffer != 0)
3672 {
3673 // Binding buffers to this binding point is not implemented yet.
3674 UNIMPLEMENTED();
3675 }
Geoff Lang3b573612016-10-31 14:08:10 -04003676 break;
3677 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003678 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003679 break;
3680 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003681 if (buffer != 0)
3682 {
3683 // Binding buffers to this binding point is not implemented yet.
3684 UNIMPLEMENTED();
3685 }
Geoff Lang3b573612016-10-31 14:08:10 -04003686 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003687
3688 default:
3689 UNREACHABLE();
3690 break;
3691 }
3692}
3693
3694void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3695{
3696 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3697 {
3698 bindReadFramebuffer(framebuffer);
3699 }
3700
3701 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3702 {
3703 bindDrawFramebuffer(framebuffer);
3704 }
3705}
3706
3707void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3708{
3709 ASSERT(target == GL_RENDERBUFFER);
3710 Renderbuffer *object =
3711 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
3712 mGLState.setRenderbufferBinding(object);
3713}
3714
JiangYizhoubddc46b2016-12-09 09:50:51 +08003715void Context::texStorage2DMultisample(GLenum target,
3716 GLsizei samples,
3717 GLenum internalformat,
3718 GLsizei width,
3719 GLsizei height,
3720 GLboolean fixedsamplelocations)
3721{
3722 Extents size(width, height, 1);
3723 Texture *texture = getTargetTexture(target);
3724 handleError(texture->setStorageMultisample(target, samples, internalformat, size,
3725 fixedsamplelocations));
3726}
3727
3728void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3729{
3730 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3731 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3732
3733 switch (pname)
3734 {
3735 case GL_SAMPLE_POSITION:
3736 handleError(framebuffer->getSamplePosition(index, val));
3737 break;
3738 default:
3739 UNREACHABLE();
3740 }
3741}
3742
Jamie Madillc29968b2016-01-20 11:17:23 -05003743} // namespace gl