blob: 1b55d55e38c2d53968361fbf0b43f2194f783057 [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);
328 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400329
Jamie Madill01a80ee2016-11-07 12:06:18 -0500330 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000331
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000332 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500333 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000334 {
335 bindIndexedUniformBuffer(0, i, 0, -1);
336 }
337
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000338 bindCopyReadBuffer(0);
339 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000340 bindPixelPackBuffer(0);
341 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000342
Geoff Langeb66a6e2016-10-31 13:06:12 -0400343 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400344 {
345 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
346 // In the initial state, a default transform feedback object is bound and treated as
347 // a transform feedback object with a name of zero. That object is bound any time
348 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400349 bindTransformFeedback(0);
350 }
Geoff Langc8058452014-02-03 12:04:11 -0500351
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700352 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500353
354 // Initialize dirty bit masks
355 // TODO(jmadill): additional ES3 state
356 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
357 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
358 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
359 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
360 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
361 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400362 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500363 // No dirty objects.
364
365 // Readpixels uses the pack state and read FBO
366 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
367 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
368 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
369 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
370 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400371 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500372 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
373
374 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
375 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
376 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
377 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
378 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
379 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
380 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
381 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
382 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
383 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
384 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
385 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
386
387 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
388 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700389 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500390 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
391 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400392
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400393 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000394}
395
396Context::~Context()
397{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700398 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000399
Corentin Wallez37c39792015-08-20 14:19:46 -0400400 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000401 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400402 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400403 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400404 {
405 SafeDelete(framebuffer.second);
406 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407 }
408
Corentin Wallez80b24112015-08-25 16:41:57 -0400409 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000410 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400411 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000412 }
413
Corentin Wallez80b24112015-08-25 16:41:57 -0400414 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000415 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400416 if (query.second != nullptr)
417 {
418 query.second->release();
419 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420 }
421
Corentin Wallez80b24112015-08-25 16:41:57 -0400422 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400423 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400424 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400425 }
426
Corentin Wallez80b24112015-08-25 16:41:57 -0400427 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500428 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500429 if (transformFeedback.second != nullptr)
430 {
431 transformFeedback.second->release();
432 }
Geoff Langc8058452014-02-03 12:04:11 -0500433 }
434
Jamie Madilldedd7b92014-11-05 16:30:36 -0500435 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400436 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500437 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400438 }
439 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000440
Corentin Wallez51706ea2015-08-07 14:39:22 -0400441 if (mCurrentSurface != nullptr)
442 {
443 releaseSurface();
444 }
445
Jamie Madill1e9ae072014-11-06 15:27:21 -0500446 if (mResourceManager)
447 {
448 mResourceManager->release();
449 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500450
451 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000452}
453
daniel@transgaming.comad629872012-11-28 19:32:06 +0000454void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000455{
Jamie Madill77a72f62015-04-14 11:18:32 -0400456 ASSERT(surface != nullptr);
457
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000458 if (!mHasBeenCurrent)
459 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000460 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500461 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400462 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700464 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
465 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000466
467 mHasBeenCurrent = true;
468 }
469
Jamie Madill1b94d432015-08-07 13:23:23 -0400470 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700471 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400472
Corentin Wallez51706ea2015-08-07 14:39:22 -0400473 if (mCurrentSurface)
474 {
475 releaseSurface();
476 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000477 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400478 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000479
Corentin Wallez37c39792015-08-20 14:19:46 -0400480 // Update default framebuffer, the binding of the previous default
481 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400482 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400483 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700484 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400485 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700486 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400487 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700488 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400489 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700490 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400491 }
492 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400493 }
Ian Ewell292f0052016-02-04 10:37:32 -0500494
495 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700496 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000497}
498
Jamie Madill77a72f62015-04-14 11:18:32 -0400499void Context::releaseSurface()
500{
Corentin Wallez37c39792015-08-20 14:19:46 -0400501 ASSERT(mCurrentSurface != nullptr);
502
503 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400504 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400505 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700506 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400507 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700508 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400509 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700510 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400511 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700512 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400513 }
514 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400515 }
516
Corentin Wallez51706ea2015-08-07 14:39:22 -0400517 mCurrentSurface->setIsCurrent(false);
518 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400519}
520
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000521GLuint Context::createBuffer()
522{
523 return mResourceManager->createBuffer();
524}
525
526GLuint Context::createProgram()
527{
Jamie Madill901b3792016-05-26 09:20:40 -0400528 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000529}
530
531GLuint Context::createShader(GLenum type)
532{
Jamie Madill901b3792016-05-26 09:20:40 -0400533 return mResourceManager->createShader(mImplementation.get(),
534 mImplementation->getNativeLimitations(), 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
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500962void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000963{
Jamie Madill901b3792016-05-26 09:20:40 -0400964 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700965 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000966}
967
Jamie Madilldedd7b92014-11-05 16:30:36 -0500968void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000969{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500970 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000971
Jamie Madilldedd7b92014-11-05 16:30:36 -0500972 if (handle == 0)
973 {
974 texture = mZeroTextures[target].get();
975 }
976 else
977 {
Jamie Madill901b3792016-05-26 09:20:40 -0400978 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500979 }
980
981 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700982 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000983}
984
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500985void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000986{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500987 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700988 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989}
990
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500991void Context::bindDrawFramebuffer(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.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995}
996
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500997void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400998{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500999 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001000 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001001}
1002
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001003void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001004{
Geoff Lang76b10c92014-09-05 16:28:14 -04001005 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001006 Sampler *sampler =
1007 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001008 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001009}
1010
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001011void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001012{
Jamie Madill901b3792016-05-26 09:20:40 -04001013 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001014 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001015}
1016
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001017void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1018 GLuint index,
1019 GLintptr offset,
1020 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001021{
Jamie Madill901b3792016-05-26 09:20:40 -04001022 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001023 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001024}
1025
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001026void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +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.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001030}
1031
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001032void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1033 GLuint index,
1034 GLintptr offset,
1035 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001036{
Jamie Madill901b3792016-05-26 09:20:40 -04001037 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001038 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001039}
1040
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001041void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +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.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001045}
1046
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001047void Context::bindCopyWriteBuffer(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.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001051}
1052
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001053void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +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.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001057}
1058
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001059void Context::bindPixelUnpackBuffer(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.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001063}
1064
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001065void Context::useProgram(GLuint program)
1066{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001067 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001068}
1069
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001070void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001071{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001072 TransformFeedback *transformFeedback =
1073 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001074 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001075}
1076
Geoff Lang5aad9672014-09-08 11:10:42 -04001077Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001078{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001079 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001080 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001081
Geoff Lang5aad9672014-09-08 11:10:42 -04001082 // begin query
1083 Error error = queryObject->begin();
1084 if (error.isError())
1085 {
1086 return error;
1087 }
1088
1089 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001090 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091
Geoff Lang5aad9672014-09-08 11:10:42 -04001092 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001093}
1094
Geoff Lang5aad9672014-09-08 11:10:42 -04001095Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001096{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001097 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001098 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001099
Geoff Lang5aad9672014-09-08 11:10:42 -04001100 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001101
Geoff Lang5aad9672014-09-08 11:10:42 -04001102 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001103 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001104
1105 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106}
1107
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001108Error Context::queryCounter(GLuint id, GLenum target)
1109{
1110 ASSERT(target == GL_TIMESTAMP_EXT);
1111
1112 Query *queryObject = getQuery(id, true, target);
1113 ASSERT(queryObject);
1114
1115 return queryObject->queryCounter();
1116}
1117
1118void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1119{
1120 switch (pname)
1121 {
1122 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001123 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001124 break;
1125 case GL_QUERY_COUNTER_BITS_EXT:
1126 switch (target)
1127 {
1128 case GL_TIME_ELAPSED_EXT:
1129 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1130 break;
1131 case GL_TIMESTAMP_EXT:
1132 params[0] = getExtensions().queryCounterBitsTimestamp;
1133 break;
1134 default:
1135 UNREACHABLE();
1136 params[0] = 0;
1137 break;
1138 }
1139 break;
1140 default:
1141 UNREACHABLE();
1142 return;
1143 }
1144}
1145
Geoff Lang2186c382016-10-14 10:54:54 -04001146void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001147{
Geoff Lang2186c382016-10-14 10:54:54 -04001148 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001149}
1150
Geoff Lang2186c382016-10-14 10:54:54 -04001151void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001152{
Geoff Lang2186c382016-10-14 10:54:54 -04001153 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001154}
1155
Geoff Lang2186c382016-10-14 10:54:54 -04001156void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001157{
Geoff Lang2186c382016-10-14 10:54:54 -04001158 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001159}
1160
Geoff Lang2186c382016-10-14 10:54:54 -04001161void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001162{
Geoff Lang2186c382016-10-14 10:54:54 -04001163 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001164}
1165
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001166Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001168 auto framebufferIt = mFramebufferMap.find(handle);
1169 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001170}
1171
Jamie Madill33dc8432013-07-26 11:55:05 -04001172FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001174 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175
Jamie Madill33dc8432013-07-26 11:55:05 -04001176 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177 {
1178 return NULL;
1179 }
1180 else
1181 {
1182 return fence->second;
1183 }
1184}
1185
1186Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1187{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001188 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189
1190 if (query == mQueryMap.end())
1191 {
1192 return NULL;
1193 }
1194 else
1195 {
1196 if (!query->second && create)
1197 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001198 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001199 query->second->addRef();
1200 }
1201 return query->second;
1202 }
1203}
1204
Geoff Lang70d0f492015-12-10 17:45:46 -05001205Query *Context::getQuery(GLuint handle) const
1206{
1207 auto iter = mQueryMap.find(handle);
1208 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1209}
1210
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001211Texture *Context::getTargetTexture(GLenum target) const
1212{
Ian Ewellbda75592016-04-18 17:25:54 -04001213 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001214 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001215}
1216
Geoff Lang76b10c92014-09-05 16:28:14 -04001217Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001219 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001220}
1221
Geoff Lang492a7e42014-11-05 13:27:06 -05001222Compiler *Context::getCompiler() const
1223{
1224 return mCompiler;
1225}
1226
Jamie Madill893ab082014-05-16 16:56:10 -04001227void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001228{
1229 switch (pname)
1230 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001231 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001232 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001234 mGLState.getBooleanv(pname, params);
1235 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237}
1238
Jamie Madill893ab082014-05-16 16:56:10 -04001239void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240{
Shannon Woods53a94a82014-06-24 15:20:36 -04001241 // Queries about context capabilities and maximums are answered by Context.
1242 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243 switch (pname)
1244 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001245 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001246 params[0] = mCaps.minAliasedLineWidth;
1247 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001248 break;
1249 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001250 params[0] = mCaps.minAliasedPointSize;
1251 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001252 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001253 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001254 ASSERT(mExtensions.textureFilterAnisotropic);
1255 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001256 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001257 case GL_MAX_TEXTURE_LOD_BIAS:
1258 *params = mCaps.maxLODBias;
1259 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001260
1261 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1262 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1263 {
1264 ASSERT(mExtensions.pathRendering);
1265 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1266 memcpy(params, m, 16 * sizeof(GLfloat));
1267 }
1268 break;
1269
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001271 mGLState.getFloatv(pname, params);
1272 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274}
1275
Jamie Madill893ab082014-05-16 16:56:10 -04001276void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277{
Shannon Woods53a94a82014-06-24 15:20:36 -04001278 // Queries about context capabilities and maximums are answered by Context.
1279 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001280
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281 switch (pname)
1282 {
Geoff Lang301d1612014-07-09 10:34:37 -04001283 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1284 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1285 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001286 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1287 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1288 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001289 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1290 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1291 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001292 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001293 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1294 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1295 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001296 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001297 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001298 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1299 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1300 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1301 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001302 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1303 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001304 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1305 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001306 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001307 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1308 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1309 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1310 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001311 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001312 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001313 break;
1314 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001315 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001316 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001317 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1318 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001319 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1320 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1321 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001322 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1323 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1324 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001325 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 case GL_MAX_VIEWPORT_DIMS:
1327 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001328 params[0] = mCaps.maxViewportWidth;
1329 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 }
1331 break;
1332 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001333 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001334 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001335 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1336 *params = mResetStrategy;
1337 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001338 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001339 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001340 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001341 case GL_SHADER_BINARY_FORMATS:
1342 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1343 break;
1344 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001345 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001346 break;
1347 case GL_PROGRAM_BINARY_FORMATS:
1348 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001349 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001350 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001351 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001352 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001353
1354 // GL_KHR_debug
1355 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1356 *params = mExtensions.maxDebugMessageLength;
1357 break;
1358 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1359 *params = mExtensions.maxDebugLoggedMessages;
1360 break;
1361 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1362 *params = mExtensions.maxDebugGroupStackDepth;
1363 break;
1364 case GL_MAX_LABEL_LENGTH:
1365 *params = mExtensions.maxLabelLength;
1366 break;
1367
Ian Ewell53f59f42016-01-28 17:36:55 -05001368 // GL_EXT_disjoint_timer_query
1369 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001370 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001371 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001372 case GL_MAX_FRAMEBUFFER_WIDTH:
1373 *params = mCaps.maxFramebufferWidth;
1374 break;
1375 case GL_MAX_FRAMEBUFFER_HEIGHT:
1376 *params = mCaps.maxFramebufferHeight;
1377 break;
1378 case GL_MAX_FRAMEBUFFER_SAMPLES:
1379 *params = mCaps.maxFramebufferSamples;
1380 break;
1381 case GL_MAX_SAMPLE_MASK_WORDS:
1382 *params = mCaps.maxSampleMaskWords;
1383 break;
1384 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1385 *params = mCaps.maxColorTextureSamples;
1386 break;
1387 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1388 *params = mCaps.maxDepthTextureSamples;
1389 break;
1390 case GL_MAX_INTEGER_SAMPLES:
1391 *params = mCaps.maxIntegerSamples;
1392 break;
1393 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1394 *params = mCaps.maxVertexAttribRelativeOffset;
1395 break;
1396 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1397 *params = mCaps.maxVertexAttribBindings;
1398 break;
1399 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1400 *params = mCaps.maxVertexAttribStride;
1401 break;
1402 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1403 *params = mCaps.maxVertexAtomicCounterBuffers;
1404 break;
1405 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1406 *params = mCaps.maxVertexAtomicCounters;
1407 break;
1408 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1409 *params = mCaps.maxVertexImageUniforms;
1410 break;
1411 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1412 *params = mCaps.maxVertexShaderStorageBlocks;
1413 break;
1414 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1415 *params = mCaps.maxFragmentAtomicCounterBuffers;
1416 break;
1417 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1418 *params = mCaps.maxFragmentAtomicCounters;
1419 break;
1420 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1421 *params = mCaps.maxFragmentImageUniforms;
1422 break;
1423 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1424 *params = mCaps.maxFragmentShaderStorageBlocks;
1425 break;
1426 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1427 *params = mCaps.minProgramTextureGatherOffset;
1428 break;
1429 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1430 *params = mCaps.maxProgramTextureGatherOffset;
1431 break;
1432 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1433 *params = mCaps.maxComputeWorkGroupInvocations;
1434 break;
1435 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1436 *params = mCaps.maxComputeUniformBlocks;
1437 break;
1438 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1439 *params = mCaps.maxComputeTextureImageUnits;
1440 break;
1441 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1442 *params = mCaps.maxComputeSharedMemorySize;
1443 break;
1444 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1445 *params = mCaps.maxComputeUniformComponents;
1446 break;
1447 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1448 *params = mCaps.maxComputeAtomicCounterBuffers;
1449 break;
1450 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1451 *params = mCaps.maxComputeAtomicCounters;
1452 break;
1453 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1454 *params = mCaps.maxComputeImageUniforms;
1455 break;
1456 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1457 *params = mCaps.maxCombinedComputeUniformComponents;
1458 break;
1459 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1460 *params = mCaps.maxComputeShaderStorageBlocks;
1461 break;
1462 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1463 *params = mCaps.maxCombinedShaderOutputResources;
1464 break;
1465 case GL_MAX_UNIFORM_LOCATIONS:
1466 *params = mCaps.maxUniformLocations;
1467 break;
1468 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1469 *params = mCaps.maxAtomicCounterBufferBindings;
1470 break;
1471 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1472 *params = mCaps.maxAtomicCounterBufferSize;
1473 break;
1474 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1475 *params = mCaps.maxCombinedAtomicCounterBuffers;
1476 break;
1477 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1478 *params = mCaps.maxCombinedAtomicCounters;
1479 break;
1480 case GL_MAX_IMAGE_UNITS:
1481 *params = mCaps.maxImageUnits;
1482 break;
1483 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1484 *params = mCaps.maxCombinedImageUniforms;
1485 break;
1486 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1487 *params = mCaps.maxShaderStorageBufferBindings;
1488 break;
1489 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1490 *params = mCaps.maxCombinedShaderStorageBlocks;
1491 break;
1492 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1493 *params = mCaps.shaderStorageBufferOffsetAlignment;
1494 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001495 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001496 mGLState.getIntegerv(mState, pname, params);
1497 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001498 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001499}
1500
Jamie Madill893ab082014-05-16 16:56:10 -04001501void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001502{
Shannon Woods53a94a82014-06-24 15:20:36 -04001503 // Queries about context capabilities and maximums are answered by Context.
1504 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001505 switch (pname)
1506 {
1507 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001508 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001509 break;
1510 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001511 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001512 break;
1513 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001514 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001515 break;
1516 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001517 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001518 break;
1519 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001520 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001521 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001522
1523 // GL_EXT_disjoint_timer_query
1524 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001525 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001526 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001527
1528 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1529 *params = mCaps.maxShaderStorageBlockSize;
1530 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001531 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001532 UNREACHABLE();
1533 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001534 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001535}
1536
Geoff Lang70d0f492015-12-10 17:45:46 -05001537void Context::getPointerv(GLenum pname, void **params) const
1538{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001539 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001540}
1541
Martin Radev66fb8202016-07-28 11:45:20 +03001542void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001543{
Shannon Woods53a94a82014-06-24 15:20:36 -04001544 // Queries about context capabilities and maximums are answered by Context.
1545 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001546
1547 GLenum nativeType;
1548 unsigned int numParams;
1549 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1550 ASSERT(queryStatus);
1551
1552 if (nativeType == GL_INT)
1553 {
1554 switch (target)
1555 {
1556 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1557 ASSERT(index < 3u);
1558 *data = mCaps.maxComputeWorkGroupCount[index];
1559 break;
1560 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1561 ASSERT(index < 3u);
1562 *data = mCaps.maxComputeWorkGroupSize[index];
1563 break;
1564 default:
1565 mGLState.getIntegeri_v(target, index, data);
1566 }
1567 }
1568 else
1569 {
1570 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1571 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001572}
1573
Martin Radev66fb8202016-07-28 11:45:20 +03001574void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001575{
Shannon Woods53a94a82014-06-24 15:20:36 -04001576 // Queries about context capabilities and maximums are answered by Context.
1577 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001578
1579 GLenum nativeType;
1580 unsigned int numParams;
1581 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1582 ASSERT(queryStatus);
1583
1584 if (nativeType == GL_INT_64_ANGLEX)
1585 {
1586 mGLState.getInteger64i_v(target, index, data);
1587 }
1588 else
1589 {
1590 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1591 }
1592}
1593
1594void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1595{
1596 // Queries about context capabilities and maximums are answered by Context.
1597 // Queries about current GL state values are answered by State.
1598
1599 GLenum nativeType;
1600 unsigned int numParams;
1601 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1602 ASSERT(queryStatus);
1603
1604 if (nativeType == GL_BOOL)
1605 {
1606 mGLState.getBooleani_v(target, index, data);
1607 }
1608 else
1609 {
1610 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1611 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001612}
1613
Geoff Langf6db0982015-08-25 13:04:00 -04001614Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001615{
Jamie Madill1b94d432015-08-07 13:23:23 -04001616 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001617 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001618 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001619
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001620 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001621}
1622
Geoff Langf6db0982015-08-25 13:04:00 -04001623Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1624{
1625 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001626 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001627 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001628
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001629 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001630}
1631
1632Error Context::drawElements(GLenum mode,
1633 GLsizei count,
1634 GLenum type,
1635 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001636 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001637{
Jamie Madill1b94d432015-08-07 13:23:23 -04001638 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001639 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001640}
1641
1642Error Context::drawElementsInstanced(GLenum mode,
1643 GLsizei count,
1644 GLenum type,
1645 const GLvoid *indices,
1646 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001647 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001648{
1649 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001650 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1651 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001652}
1653
1654Error Context::drawRangeElements(GLenum mode,
1655 GLuint start,
1656 GLuint end,
1657 GLsizei count,
1658 GLenum type,
1659 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001660 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001661{
1662 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001663 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001664}
1665
Geoff Lang129753a2015-01-09 16:52:09 -05001666Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001667{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001668 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001669}
1670
1671Error Context::finish()
1672{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001673 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001674}
1675
Austin Kinross6ee1e782015-05-29 17:05:37 -07001676void Context::insertEventMarker(GLsizei length, const char *marker)
1677{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001678 ASSERT(mImplementation);
1679 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001680}
1681
1682void Context::pushGroupMarker(GLsizei length, const char *marker)
1683{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001684 ASSERT(mImplementation);
1685 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001686}
1687
1688void Context::popGroupMarker()
1689{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001690 ASSERT(mImplementation);
1691 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001692}
1693
Geoff Langd8605522016-04-13 10:19:12 -04001694void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1695{
1696 Program *programObject = getProgram(program);
1697 ASSERT(programObject);
1698
1699 programObject->bindUniformLocation(location, name);
1700}
1701
Sami Väisänena797e062016-05-12 15:23:40 +03001702void Context::setCoverageModulation(GLenum components)
1703{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001704 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001705}
1706
Sami Väisänene45e53b2016-05-25 10:36:04 +03001707void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1708{
1709 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1710}
1711
1712void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1713{
1714 GLfloat I[16];
1715 angle::Matrix<GLfloat>::setToIdentity(I);
1716
1717 mGLState.loadPathRenderingMatrix(matrixMode, I);
1718}
1719
1720void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1721{
1722 const auto *pathObj = mResourceManager->getPath(path);
1723 if (!pathObj)
1724 return;
1725
1726 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1727 syncRendererState();
1728
1729 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1730}
1731
1732void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1733{
1734 const auto *pathObj = mResourceManager->getPath(path);
1735 if (!pathObj)
1736 return;
1737
1738 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1739 syncRendererState();
1740
1741 mImplementation->stencilStrokePath(pathObj, reference, mask);
1742}
1743
1744void Context::coverFillPath(GLuint path, GLenum coverMode)
1745{
1746 const auto *pathObj = mResourceManager->getPath(path);
1747 if (!pathObj)
1748 return;
1749
1750 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1751 syncRendererState();
1752
1753 mImplementation->coverFillPath(pathObj, coverMode);
1754}
1755
1756void Context::coverStrokePath(GLuint path, GLenum coverMode)
1757{
1758 const auto *pathObj = mResourceManager->getPath(path);
1759 if (!pathObj)
1760 return;
1761
1762 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1763 syncRendererState();
1764
1765 mImplementation->coverStrokePath(pathObj, coverMode);
1766}
1767
1768void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1769{
1770 const auto *pathObj = mResourceManager->getPath(path);
1771 if (!pathObj)
1772 return;
1773
1774 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1775 syncRendererState();
1776
1777 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1778}
1779
1780void Context::stencilThenCoverStrokePath(GLuint path,
1781 GLint reference,
1782 GLuint mask,
1783 GLenum coverMode)
1784{
1785 const auto *pathObj = mResourceManager->getPath(path);
1786 if (!pathObj)
1787 return;
1788
1789 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1790 syncRendererState();
1791
1792 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1793}
1794
Sami Väisänend59ca052016-06-21 16:10:00 +03001795void Context::coverFillPathInstanced(GLsizei numPaths,
1796 GLenum pathNameType,
1797 const void *paths,
1798 GLuint pathBase,
1799 GLenum coverMode,
1800 GLenum transformType,
1801 const GLfloat *transformValues)
1802{
1803 const auto &pathObjects =
1804 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1805
1806 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1807 syncRendererState();
1808
1809 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1810}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001811
Sami Väisänend59ca052016-06-21 16:10:00 +03001812void Context::coverStrokePathInstanced(GLsizei numPaths,
1813 GLenum pathNameType,
1814 const void *paths,
1815 GLuint pathBase,
1816 GLenum coverMode,
1817 GLenum transformType,
1818 const GLfloat *transformValues)
1819{
1820 const auto &pathObjects =
1821 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1822
1823 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1824 syncRendererState();
1825
1826 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1827 transformValues);
1828}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001829
Sami Väisänend59ca052016-06-21 16:10:00 +03001830void Context::stencilFillPathInstanced(GLsizei numPaths,
1831 GLenum pathNameType,
1832 const void *paths,
1833 GLuint pathBase,
1834 GLenum fillMode,
1835 GLuint mask,
1836 GLenum transformType,
1837 const GLfloat *transformValues)
1838{
1839 const auto &pathObjects =
1840 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1841
1842 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1843 syncRendererState();
1844
1845 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1846 transformValues);
1847}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001848
Sami Väisänend59ca052016-06-21 16:10:00 +03001849void Context::stencilStrokePathInstanced(GLsizei numPaths,
1850 GLenum pathNameType,
1851 const void *paths,
1852 GLuint pathBase,
1853 GLint reference,
1854 GLuint mask,
1855 GLenum transformType,
1856 const GLfloat *transformValues)
1857{
1858 const auto &pathObjects =
1859 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1860
1861 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1862 syncRendererState();
1863
1864 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1865 transformValues);
1866}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001867
Sami Väisänend59ca052016-06-21 16:10:00 +03001868void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1869 GLenum pathNameType,
1870 const void *paths,
1871 GLuint pathBase,
1872 GLenum fillMode,
1873 GLuint mask,
1874 GLenum coverMode,
1875 GLenum transformType,
1876 const GLfloat *transformValues)
1877{
1878 const auto &pathObjects =
1879 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1880
1881 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1882 syncRendererState();
1883
1884 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1885 transformType, transformValues);
1886}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001887
Sami Väisänend59ca052016-06-21 16:10:00 +03001888void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1889 GLenum pathNameType,
1890 const void *paths,
1891 GLuint pathBase,
1892 GLint reference,
1893 GLuint mask,
1894 GLenum coverMode,
1895 GLenum transformType,
1896 const GLfloat *transformValues)
1897{
1898 const auto &pathObjects =
1899 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1900
1901 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1902 syncRendererState();
1903
1904 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1905 transformType, transformValues);
1906}
1907
Sami Väisänen46eaa942016-06-29 10:26:37 +03001908void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1909{
1910 auto *programObject = getProgram(program);
1911
1912 programObject->bindFragmentInputLocation(location, name);
1913}
1914
1915void Context::programPathFragmentInputGen(GLuint program,
1916 GLint location,
1917 GLenum genMode,
1918 GLint components,
1919 const GLfloat *coeffs)
1920{
1921 auto *programObject = getProgram(program);
1922
1923 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1924}
1925
Jamie Madill437fa652016-05-03 15:13:24 -04001926void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001927{
Geoff Langda5777c2014-07-11 09:52:58 -04001928 if (error.isError())
1929 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001930 GLenum code = error.getCode();
1931 mErrors.insert(code);
1932 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1933 {
1934 markContextLost();
1935 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001936
1937 if (!error.getMessage().empty())
1938 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001939 auto *debug = &mGLState.getDebug();
1940 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1941 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001942 }
Geoff Langda5777c2014-07-11 09:52:58 -04001943 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001944}
1945
1946// Get one of the recorded errors and clear its flag, if any.
1947// [OpenGL ES 2.0.24] section 2.5 page 13.
1948GLenum Context::getError()
1949{
Geoff Langda5777c2014-07-11 09:52:58 -04001950 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001951 {
Geoff Langda5777c2014-07-11 09:52:58 -04001952 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001953 }
Geoff Langda5777c2014-07-11 09:52:58 -04001954 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001955 {
Geoff Langda5777c2014-07-11 09:52:58 -04001956 GLenum error = *mErrors.begin();
1957 mErrors.erase(mErrors.begin());
1958 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001959 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001960}
1961
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001962// NOTE: this function should not assume that this context is current!
1963void Context::markContextLost()
1964{
1965 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001966 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001967 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001968 mContextLostForced = true;
1969 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001970 mContextLost = true;
1971}
1972
1973bool Context::isContextLost()
1974{
1975 return mContextLost;
1976}
1977
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001978GLenum Context::getResetStatus()
1979{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001980 // Even if the application doesn't want to know about resets, we want to know
1981 // as it will allow us to skip all the calls.
1982 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001983 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001984 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001985 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001986 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001987 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001988
1989 // EXT_robustness, section 2.6: If the reset notification behavior is
1990 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1991 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1992 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001993 }
1994
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001995 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1996 // status should be returned at least once, and GL_NO_ERROR should be returned
1997 // once the device has finished resetting.
1998 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001999 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002000 ASSERT(mResetStatus == GL_NO_ERROR);
2001 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002002
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002003 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002004 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002005 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002006 }
2007 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002008 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002009 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002010 // If markContextLost was used to mark the context lost then
2011 // assume that is not recoverable, and continue to report the
2012 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002013 mResetStatus = mImplementation->getResetStatus();
2014 }
Jamie Madill893ab082014-05-16 16:56:10 -04002015
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002016 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002017}
2018
2019bool Context::isResetNotificationEnabled()
2020{
2021 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2022}
2023
Corentin Walleze3b10e82015-05-20 11:06:25 -04002024const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002025{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002026 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002027}
2028
2029EGLenum Context::getClientType() const
2030{
2031 return mClientType;
2032}
2033
2034EGLenum Context::getRenderBuffer() const
2035{
Corentin Wallez37c39792015-08-20 14:19:46 -04002036 auto framebufferIt = mFramebufferMap.find(0);
2037 if (framebufferIt != mFramebufferMap.end())
2038 {
2039 const Framebuffer *framebuffer = framebufferIt->second;
2040 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2041
2042 ASSERT(backAttachment != nullptr);
2043 return backAttachment->getSurface()->getRenderBuffer();
2044 }
2045 else
2046 {
2047 return EGL_NONE;
2048 }
Régis Fénéon83107972015-02-05 12:57:44 +01002049}
2050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002051VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002052{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002053 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002054 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2055 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002056 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002057 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2058
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002059 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002060 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002061
2062 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002063}
2064
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002065TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002066{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002067 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002068 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2069 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002070 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002071 transformFeedback =
2072 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002073 transformFeedback->addRef();
2074 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002075 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002076
2077 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002078}
2079
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002080Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2081{
2082 // Can be called from Bind without a prior call to Gen.
2083 auto framebufferIt = mFramebufferMap.find(framebuffer);
2084 bool neverCreated = framebufferIt == mFramebufferMap.end();
2085 if (neverCreated || framebufferIt->second == nullptr)
2086 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002087 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002088 if (neverCreated)
2089 {
2090 mFramebufferHandleAllocator.reserve(framebuffer);
2091 mFramebufferMap[framebuffer] = newFBO;
2092 return newFBO;
2093 }
2094
2095 framebufferIt->second = newFBO;
2096 }
2097
2098 return framebufferIt->second;
2099}
2100
Geoff Lang36167ab2015-12-07 10:27:14 -05002101bool Context::isVertexArrayGenerated(GLuint vertexArray)
2102{
Geoff Langf41a7152016-09-19 15:11:17 -04002103 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002104 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2105}
2106
2107bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2108{
Geoff Langf41a7152016-09-19 15:11:17 -04002109 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002110 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2111}
2112
Shannon Woods53a94a82014-06-24 15:20:36 -04002113void Context::detachTexture(GLuint texture)
2114{
2115 // Simple pass-through to State's detachTexture method, as textures do not require
2116 // allocation map management either here or in the resource manager at detach time.
2117 // Zero textures are held by the Context, and we don't attempt to request them from
2118 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002119 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002120}
2121
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002122void Context::detachBuffer(GLuint buffer)
2123{
Yuly Novikov5807a532015-12-03 13:01:22 -05002124 // Simple pass-through to State's detachBuffer method, since
2125 // only buffer attachments to container objects that are bound to the current context
2126 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002127
Yuly Novikov5807a532015-12-03 13:01:22 -05002128 // [OpenGL ES 3.2] section 5.1.2 page 45:
2129 // Attachments to unbound container objects, such as
2130 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2131 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002132 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002133}
2134
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002135void Context::detachFramebuffer(GLuint framebuffer)
2136{
Shannon Woods53a94a82014-06-24 15:20:36 -04002137 // Framebuffer detachment is handled by Context, because 0 is a valid
2138 // Framebuffer object, and a pointer to it must be passed from Context
2139 // to State at binding time.
2140
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002141 // [OpenGL ES 2.0.24] section 4.4 page 107:
2142 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2143 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2144
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002145 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002146 {
2147 bindReadFramebuffer(0);
2148 }
2149
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002150 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002151 {
2152 bindDrawFramebuffer(0);
2153 }
2154}
2155
2156void Context::detachRenderbuffer(GLuint renderbuffer)
2157{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002158 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002159}
2160
Jamie Madill57a89722013-07-02 11:57:03 -04002161void Context::detachVertexArray(GLuint vertexArray)
2162{
Jamie Madill77a72f62015-04-14 11:18:32 -04002163 // Vertex array detachment is handled by Context, because 0 is a valid
2164 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002165 // binding time.
2166
Jamie Madill57a89722013-07-02 11:57:03 -04002167 // [OpenGL ES 3.0.2] section 2.10 page 43:
2168 // If a vertex array object that is currently bound is deleted, the binding
2169 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002170 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002171 {
2172 bindVertexArray(0);
2173 }
2174}
2175
Geoff Langc8058452014-02-03 12:04:11 -05002176void Context::detachTransformFeedback(GLuint transformFeedback)
2177{
Corentin Walleza2257da2016-04-19 16:43:12 -04002178 // Transform feedback detachment is handled by Context, because 0 is a valid
2179 // transform feedback, and a pointer to it must be passed from Context to State at
2180 // binding time.
2181
2182 // The OpenGL specification doesn't mention what should happen when the currently bound
2183 // transform feedback object is deleted. Since it is a container object, we treat it like
2184 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002185 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002186 {
2187 bindTransformFeedback(0);
2188 }
Geoff Langc8058452014-02-03 12:04:11 -05002189}
2190
Jamie Madilldc356042013-07-19 16:36:57 -04002191void Context::detachSampler(GLuint sampler)
2192{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002193 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002194}
2195
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002196void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2197{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002198 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002199}
2200
Jamie Madille29d1672013-07-19 16:36:57 -04002201void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2202{
Geoff Langc1984ed2016-10-07 12:41:00 -04002203 Sampler *samplerObject =
2204 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2205 SetSamplerParameteri(samplerObject, pname, param);
2206}
Jamie Madille29d1672013-07-19 16:36:57 -04002207
Geoff Langc1984ed2016-10-07 12:41:00 -04002208void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2209{
2210 Sampler *samplerObject =
2211 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2212 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002213}
2214
2215void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2216{
Geoff Langc1984ed2016-10-07 12:41:00 -04002217 Sampler *samplerObject =
2218 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2219 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002220}
2221
Geoff Langc1984ed2016-10-07 12:41:00 -04002222void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002223{
Geoff Langc1984ed2016-10-07 12:41:00 -04002224 Sampler *samplerObject =
2225 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2226 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002227}
2228
Geoff Langc1984ed2016-10-07 12:41:00 -04002229void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002230{
Geoff Langc1984ed2016-10-07 12:41:00 -04002231 const Sampler *samplerObject =
2232 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2233 QuerySamplerParameteriv(samplerObject, pname, params);
2234}
Jamie Madill9675b802013-07-19 16:36:59 -04002235
Geoff Langc1984ed2016-10-07 12:41:00 -04002236void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2237{
2238 const Sampler *samplerObject =
2239 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2240 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002241}
2242
Olli Etuahof0fee072016-03-30 15:11:58 +03002243void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2244{
2245 gl::Program *programObject = getProgram(program);
2246 ASSERT(programObject != nullptr);
2247
2248 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2249 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2250}
2251
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002252void Context::initRendererString()
2253{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002254 std::ostringstream rendererString;
2255 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002256 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002257 rendererString << ")";
2258
Geoff Langcec35902014-04-16 10:52:36 -04002259 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002260}
2261
Geoff Langc339c4e2016-11-29 10:37:36 -05002262void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002263{
Geoff Langc339c4e2016-11-29 10:37:36 -05002264 const Version &clientVersion = getClientVersion();
2265
2266 std::ostringstream versionString;
2267 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2268 << ANGLE_VERSION_STRING << ")";
2269 mVersionString = MakeStaticString(versionString.str());
2270
2271 std::ostringstream shadingLanguageVersionString;
2272 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2273 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2274 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2275 << ")";
2276 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002277}
2278
Geoff Langcec35902014-04-16 10:52:36 -04002279void Context::initExtensionStrings()
2280{
Geoff Langc339c4e2016-11-29 10:37:36 -05002281 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2282 std::ostringstream combinedStringStream;
2283 std::copy(strings.begin(), strings.end(),
2284 std::ostream_iterator<const char *>(combinedStringStream, " "));
2285 return MakeStaticString(combinedStringStream.str());
2286 };
2287
2288 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002289 for (const auto &extensionString : mExtensions.getStrings())
2290 {
2291 mExtensionStrings.push_back(MakeStaticString(extensionString));
2292 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002293 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002294
Geoff Langc339c4e2016-11-29 10:37:36 -05002295 mRequestableExtensionStrings.clear();
2296 for (const auto &extensionInfo : GetExtensionInfoMap())
2297 {
2298 if (extensionInfo.second.Requestable &&
2299 !(mExtensions.*(extensionInfo.second.ExtensionsMember)))
2300 {
2301 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2302 }
2303 }
2304 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002305}
2306
Geoff Langc339c4e2016-11-29 10:37:36 -05002307const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002308{
Geoff Langc339c4e2016-11-29 10:37:36 -05002309 switch (name)
2310 {
2311 case GL_VENDOR:
2312 return reinterpret_cast<const GLubyte *>("Google Inc.");
2313
2314 case GL_RENDERER:
2315 return reinterpret_cast<const GLubyte *>(mRendererString);
2316
2317 case GL_VERSION:
2318 return reinterpret_cast<const GLubyte *>(mVersionString);
2319
2320 case GL_SHADING_LANGUAGE_VERSION:
2321 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2322
2323 case GL_EXTENSIONS:
2324 return reinterpret_cast<const GLubyte *>(mExtensionString);
2325
2326 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2327 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2328
2329 default:
2330 UNREACHABLE();
2331 return nullptr;
2332 }
Geoff Langcec35902014-04-16 10:52:36 -04002333}
2334
Geoff Langc339c4e2016-11-29 10:37:36 -05002335const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002336{
Geoff Langc339c4e2016-11-29 10:37:36 -05002337 switch (name)
2338 {
2339 case GL_EXTENSIONS:
2340 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2341
2342 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2343 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2344
2345 default:
2346 UNREACHABLE();
2347 return nullptr;
2348 }
Geoff Langcec35902014-04-16 10:52:36 -04002349}
2350
2351size_t Context::getExtensionStringCount() const
2352{
2353 return mExtensionStrings.size();
2354}
2355
Geoff Langc339c4e2016-11-29 10:37:36 -05002356void Context::requestExtension(const char *name)
2357{
2358 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2359 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2360 const auto &extension = extensionInfos.at(name);
2361 ASSERT(extension.Requestable);
2362
2363 if (mExtensions.*(extension.ExtensionsMember))
2364 {
2365 // Extension already enabled
2366 return;
2367 }
2368
2369 mExtensions.*(extension.ExtensionsMember) = true;
2370 updateCaps();
2371 initExtensionStrings();
2372}
2373
2374size_t Context::getRequestableExtensionStringCount() const
2375{
2376 return mRequestableExtensionStrings.size();
2377}
2378
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002379void Context::beginTransformFeedback(GLenum primitiveMode)
2380{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002381 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002382 ASSERT(transformFeedback != nullptr);
2383 ASSERT(!transformFeedback->isPaused());
2384
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002385 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002386}
2387
2388bool Context::hasActiveTransformFeedback(GLuint program) const
2389{
2390 for (auto pair : mTransformFeedbackMap)
2391 {
2392 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2393 {
2394 return true;
2395 }
2396 }
2397 return false;
2398}
2399
Geoff Langc287ea62016-09-16 14:46:51 -04002400void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002401{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002402 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002403
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002404 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002405
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002406 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002407
Geoff Langeb66a6e2016-10-31 13:06:12 -04002408 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002409 {
2410 // Disable ES3+ extensions
2411 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002412 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002413 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002414 }
2415
Geoff Langeb66a6e2016-10-31 13:06:12 -04002416 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002417 {
2418 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2419 //mExtensions.sRGB = false;
2420 }
2421
Jamie Madill00ed7a12016-05-19 13:13:38 -04002422 // Some extensions are always available because they are implemented in the GL layer.
2423 mExtensions.bindUniformLocation = true;
2424 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002425 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002426 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002427
2428 // Enable the no error extension if the context was created with the flag.
2429 mExtensions.noError = mSkipValidation;
2430
Geoff Lang70d0f492015-12-10 17:45:46 -05002431 // Explicitly enable GL_KHR_debug
2432 mExtensions.debug = true;
2433 mExtensions.maxDebugMessageLength = 1024;
2434 mExtensions.maxDebugLoggedMessages = 1024;
2435 mExtensions.maxDebugGroupStackDepth = 1024;
2436 mExtensions.maxLabelLength = 1024;
2437
Geoff Langff5b2d52016-09-07 11:32:23 -04002438 // Explicitly enable GL_ANGLE_robust_client_memory
2439 mExtensions.robustClientMemory = true;
2440
Geoff Lang301d1612014-07-09 10:34:37 -04002441 // Apply implementation limits
2442 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002443 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2444 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2445
2446 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002447
Geoff Langc287ea62016-09-16 14:46:51 -04002448 // WebGL compatibility
2449 mExtensions.webglCompatibility = webGLContext;
2450 for (const auto &extensionInfo : GetExtensionInfoMap())
2451 {
2452 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002453 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002454 {
2455 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2456 }
2457 }
2458
2459 // Generate texture caps
2460 updateCaps();
2461}
2462
2463void Context::updateCaps()
2464{
Geoff Lang900013c2014-07-07 11:32:19 -04002465 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002466 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002467
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002468 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002469 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2470 {
2471 GLenum format = i->first;
2472 TextureCaps formatCaps = i->second;
2473
Geoff Lang5d601382014-07-22 15:14:06 -04002474 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002475
Geoff Lang0d8b7242015-09-09 14:56:53 -04002476 // Update the format caps based on the client version and extensions.
2477 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2478 // ES3.
2479 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002480 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002481 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002482 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002483 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002484 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002485
2486 // OpenGL ES does not support multisampling with integer formats
2487 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002488 {
Geoff Langd87878e2014-09-19 15:42:59 -04002489 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002490 }
Geoff Langd87878e2014-09-19 15:42:59 -04002491
2492 if (formatCaps.texturable && formatInfo.compressed)
2493 {
2494 mCaps.compressedTextureFormats.push_back(format);
2495 }
2496
2497 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002498 }
2499}
2500
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002501void Context::initWorkarounds()
2502{
2503 // Lose the context upon out of memory error if the application is
2504 // expecting to watch for those events.
2505 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2506}
2507
Jamie Madill1b94d432015-08-07 13:23:23 -04002508void Context::syncRendererState()
2509{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002510 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2511 mImplementation->syncState(mGLState, dirtyBits);
2512 mGLState.clearDirtyBits();
2513 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002514}
2515
Jamie Madillad9f24e2016-02-12 09:27:24 -05002516void Context::syncRendererState(const State::DirtyBits &bitMask,
2517 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002518{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002519 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2520 mImplementation->syncState(mGLState, dirtyBits);
2521 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002522
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002523 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002524}
Jamie Madillc29968b2016-01-20 11:17:23 -05002525
2526void Context::blitFramebuffer(GLint srcX0,
2527 GLint srcY0,
2528 GLint srcX1,
2529 GLint srcY1,
2530 GLint dstX0,
2531 GLint dstY0,
2532 GLint dstX1,
2533 GLint dstY1,
2534 GLbitfield mask,
2535 GLenum filter)
2536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002537 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 ASSERT(drawFramebuffer);
2539
2540 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2541 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2542
Jamie Madillad9f24e2016-02-12 09:27:24 -05002543 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002544
Jamie Madill8415b5f2016-04-26 13:41:39 -04002545 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002546}
Jamie Madillc29968b2016-01-20 11:17:23 -05002547
2548void Context::clear(GLbitfield mask)
2549{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002550 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002551 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002552}
2553
2554void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2555{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002556 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002557 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2558 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002559}
2560
2561void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2562{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002563 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002564 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2565 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002566}
2567
2568void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2569{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002570 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002571 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2572 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002573}
2574
2575void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2576{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002577 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002578 ASSERT(framebufferObject);
2579
2580 // If a buffer is not present, the clear has no effect
2581 if (framebufferObject->getDepthbuffer() == nullptr &&
2582 framebufferObject->getStencilbuffer() == nullptr)
2583 {
2584 return;
2585 }
2586
Jamie Madillad9f24e2016-02-12 09:27:24 -05002587 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002588 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2589 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002590}
2591
2592void Context::readPixels(GLint x,
2593 GLint y,
2594 GLsizei width,
2595 GLsizei height,
2596 GLenum format,
2597 GLenum type,
2598 GLvoid *pixels)
2599{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002600 if (width == 0 || height == 0)
2601 {
2602 return;
2603 }
2604
Jamie Madillad9f24e2016-02-12 09:27:24 -05002605 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002606
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002607 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002608 ASSERT(framebufferObject);
2609
2610 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002611 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002612}
2613
2614void Context::copyTexImage2D(GLenum target,
2615 GLint level,
2616 GLenum internalformat,
2617 GLint x,
2618 GLint y,
2619 GLsizei width,
2620 GLsizei height,
2621 GLint border)
2622{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002623 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002624 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002625
Jamie Madillc29968b2016-01-20 11:17:23 -05002626 Rectangle sourceArea(x, y, width, height);
2627
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002628 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002629 Texture *texture =
2630 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002631 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002632}
2633
2634void Context::copyTexSubImage2D(GLenum target,
2635 GLint level,
2636 GLint xoffset,
2637 GLint yoffset,
2638 GLint x,
2639 GLint y,
2640 GLsizei width,
2641 GLsizei height)
2642{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002643 if (width == 0 || height == 0)
2644 {
2645 return;
2646 }
2647
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002648 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002649 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002650
Jamie Madillc29968b2016-01-20 11:17:23 -05002651 Offset destOffset(xoffset, yoffset, 0);
2652 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->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002658}
2659
2660void Context::copyTexSubImage3D(GLenum target,
2661 GLint level,
2662 GLint xoffset,
2663 GLint yoffset,
2664 GLint zoffset,
2665 GLint x,
2666 GLint y,
2667 GLsizei width,
2668 GLsizei height)
2669{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002670 if (width == 0 || height == 0)
2671 {
2672 return;
2673 }
2674
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002675 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002676 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002677
Jamie Madillc29968b2016-01-20 11:17:23 -05002678 Offset destOffset(xoffset, yoffset, zoffset);
2679 Rectangle sourceArea(x, y, width, height);
2680
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002681 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002682 Texture *texture = getTargetTexture(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::framebufferTexture2D(GLenum target,
2687 GLenum attachment,
2688 GLenum textarget,
2689 GLuint texture,
2690 GLint level)
2691{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002692 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002693 ASSERT(framebuffer);
2694
2695 if (texture != 0)
2696 {
2697 Texture *textureObj = getTexture(texture);
2698
2699 ImageIndex index = ImageIndex::MakeInvalid();
2700
2701 if (textarget == GL_TEXTURE_2D)
2702 {
2703 index = ImageIndex::Make2D(level);
2704 }
2705 else
2706 {
2707 ASSERT(IsCubeMapTextureTarget(textarget));
2708 index = ImageIndex::MakeCube(textarget, level);
2709 }
2710
2711 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2712 }
2713 else
2714 {
2715 framebuffer->resetAttachment(attachment);
2716 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002717
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002718 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002719}
2720
2721void Context::framebufferRenderbuffer(GLenum target,
2722 GLenum attachment,
2723 GLenum renderbuffertarget,
2724 GLuint renderbuffer)
2725{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002726 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002727 ASSERT(framebuffer);
2728
2729 if (renderbuffer != 0)
2730 {
2731 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2732 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2733 renderbufferObject);
2734 }
2735 else
2736 {
2737 framebuffer->resetAttachment(attachment);
2738 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002739
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002740 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002741}
2742
2743void Context::framebufferTextureLayer(GLenum target,
2744 GLenum attachment,
2745 GLuint texture,
2746 GLint level,
2747 GLint layer)
2748{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002749 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002750 ASSERT(framebuffer);
2751
2752 if (texture != 0)
2753 {
2754 Texture *textureObject = getTexture(texture);
2755
2756 ImageIndex index = ImageIndex::MakeInvalid();
2757
2758 if (textureObject->getTarget() == GL_TEXTURE_3D)
2759 {
2760 index = ImageIndex::Make3D(level, layer);
2761 }
2762 else
2763 {
2764 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2765 index = ImageIndex::Make2DArray(level, layer);
2766 }
2767
2768 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2769 }
2770 else
2771 {
2772 framebuffer->resetAttachment(attachment);
2773 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002774
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002775 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002776}
2777
2778void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2779{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002780 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002781 ASSERT(framebuffer);
2782 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002783 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002784}
2785
2786void Context::readBuffer(GLenum mode)
2787{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002788 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002789 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002790 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002791}
2792
2793void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2794{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002795 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002796 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002797
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002798 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002799 ASSERT(framebuffer);
2800
2801 // The specification isn't clear what should be done when the framebuffer isn't complete.
2802 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002803 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002804}
2805
2806void Context::invalidateFramebuffer(GLenum target,
2807 GLsizei numAttachments,
2808 const GLenum *attachments)
2809{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002810 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002811 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002812
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002813 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002814 ASSERT(framebuffer);
2815
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002816 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002817 {
Jamie Madill437fa652016-05-03 15:13:24 -04002818 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002819 }
Jamie Madill437fa652016-05-03 15:13:24 -04002820
2821 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002822}
2823
2824void Context::invalidateSubFramebuffer(GLenum target,
2825 GLsizei numAttachments,
2826 const GLenum *attachments,
2827 GLint x,
2828 GLint y,
2829 GLsizei width,
2830 GLsizei height)
2831{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002832 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002833 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002834
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002835 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002836 ASSERT(framebuffer);
2837
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002838 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002839 {
Jamie Madill437fa652016-05-03 15:13:24 -04002840 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002841 }
Jamie Madill437fa652016-05-03 15:13:24 -04002842
2843 Rectangle area(x, y, width, height);
2844 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002845}
2846
Jamie Madill73a84962016-02-12 09:27:23 -05002847void Context::texImage2D(GLenum target,
2848 GLint level,
2849 GLint internalformat,
2850 GLsizei width,
2851 GLsizei height,
2852 GLint border,
2853 GLenum format,
2854 GLenum type,
2855 const GLvoid *pixels)
2856{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002857 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002858
2859 Extents size(width, height, 1);
2860 Texture *texture =
2861 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002862 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002863 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002864}
2865
2866void Context::texImage3D(GLenum target,
2867 GLint level,
2868 GLint internalformat,
2869 GLsizei width,
2870 GLsizei height,
2871 GLsizei depth,
2872 GLint border,
2873 GLenum format,
2874 GLenum type,
2875 const GLvoid *pixels)
2876{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002877 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002878
2879 Extents size(width, height, depth);
2880 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002881 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002882 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002883}
2884
2885void Context::texSubImage2D(GLenum target,
2886 GLint level,
2887 GLint xoffset,
2888 GLint yoffset,
2889 GLsizei width,
2890 GLsizei height,
2891 GLenum format,
2892 GLenum type,
2893 const GLvoid *pixels)
2894{
2895 // Zero sized uploads are valid but no-ops
2896 if (width == 0 || height == 0)
2897 {
2898 return;
2899 }
2900
Jamie Madillad9f24e2016-02-12 09:27:24 -05002901 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002902
2903 Box area(xoffset, yoffset, 0, width, height, 1);
2904 Texture *texture =
2905 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002906 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002907 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002908}
2909
2910void Context::texSubImage3D(GLenum target,
2911 GLint level,
2912 GLint xoffset,
2913 GLint yoffset,
2914 GLint zoffset,
2915 GLsizei width,
2916 GLsizei height,
2917 GLsizei depth,
2918 GLenum format,
2919 GLenum type,
2920 const GLvoid *pixels)
2921{
2922 // Zero sized uploads are valid but no-ops
2923 if (width == 0 || height == 0 || depth == 0)
2924 {
2925 return;
2926 }
2927
Jamie Madillad9f24e2016-02-12 09:27:24 -05002928 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002929
2930 Box area(xoffset, yoffset, zoffset, width, height, depth);
2931 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002932 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002933 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002934}
2935
2936void Context::compressedTexImage2D(GLenum target,
2937 GLint level,
2938 GLenum internalformat,
2939 GLsizei width,
2940 GLsizei height,
2941 GLint border,
2942 GLsizei imageSize,
2943 const GLvoid *data)
2944{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002945 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002946
2947 Extents size(width, height, 1);
2948 Texture *texture =
2949 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002950 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2951 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002952 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002953}
2954
2955void Context::compressedTexImage3D(GLenum target,
2956 GLint level,
2957 GLenum internalformat,
2958 GLsizei width,
2959 GLsizei height,
2960 GLsizei depth,
2961 GLint border,
2962 GLsizei imageSize,
2963 const GLvoid *data)
2964{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002965 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002966
2967 Extents size(width, height, depth);
2968 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002969 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2970 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002971 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002972}
2973
2974void Context::compressedTexSubImage2D(GLenum target,
2975 GLint level,
2976 GLint xoffset,
2977 GLint yoffset,
2978 GLsizei width,
2979 GLsizei height,
2980 GLenum format,
2981 GLsizei imageSize,
2982 const GLvoid *data)
2983{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002984 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002985
2986 Box area(xoffset, yoffset, 0, width, height, 1);
2987 Texture *texture =
2988 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002989 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2990 format, imageSize,
2991 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002992}
2993
2994void Context::compressedTexSubImage3D(GLenum target,
2995 GLint level,
2996 GLint xoffset,
2997 GLint yoffset,
2998 GLint zoffset,
2999 GLsizei width,
3000 GLsizei height,
3001 GLsizei depth,
3002 GLenum format,
3003 GLsizei imageSize,
3004 const GLvoid *data)
3005{
3006 // Zero sized uploads are valid but no-ops
3007 if (width == 0 || height == 0)
3008 {
3009 return;
3010 }
3011
Jamie Madillad9f24e2016-02-12 09:27:24 -05003012 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003013
3014 Box area(xoffset, yoffset, zoffset, width, height, depth);
3015 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003016 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3017 format, imageSize,
3018 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003019}
3020
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003021void Context::generateMipmap(GLenum target)
3022{
3023 Texture *texture = getTargetTexture(target);
3024 handleError(texture->generateMipmap());
3025}
3026
Geoff Lang97073d12016-04-20 10:42:34 -07003027void Context::copyTextureCHROMIUM(GLuint sourceId,
3028 GLuint destId,
3029 GLint internalFormat,
3030 GLenum destType,
3031 GLboolean unpackFlipY,
3032 GLboolean unpackPremultiplyAlpha,
3033 GLboolean unpackUnmultiplyAlpha)
3034{
3035 syncStateForTexImage();
3036
3037 gl::Texture *sourceTexture = getTexture(sourceId);
3038 gl::Texture *destTexture = getTexture(destId);
3039 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3040 unpackPremultiplyAlpha == GL_TRUE,
3041 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3042}
3043
3044void Context::copySubTextureCHROMIUM(GLuint sourceId,
3045 GLuint destId,
3046 GLint xoffset,
3047 GLint yoffset,
3048 GLint x,
3049 GLint y,
3050 GLsizei width,
3051 GLsizei height,
3052 GLboolean unpackFlipY,
3053 GLboolean unpackPremultiplyAlpha,
3054 GLboolean unpackUnmultiplyAlpha)
3055{
3056 // Zero sized copies are valid but no-ops
3057 if (width == 0 || height == 0)
3058 {
3059 return;
3060 }
3061
3062 syncStateForTexImage();
3063
3064 gl::Texture *sourceTexture = getTexture(sourceId);
3065 gl::Texture *destTexture = getTexture(destId);
3066 Offset offset(xoffset, yoffset, 0);
3067 Rectangle area(x, y, width, height);
3068 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3069 unpackPremultiplyAlpha == GL_TRUE,
3070 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3071}
3072
Geoff Lang47110bf2016-04-20 11:13:22 -07003073void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3074{
3075 syncStateForTexImage();
3076
3077 gl::Texture *sourceTexture = getTexture(sourceId);
3078 gl::Texture *destTexture = getTexture(destId);
3079 handleError(destTexture->copyCompressedTexture(sourceTexture));
3080}
3081
Geoff Lang496c02d2016-10-20 11:38:11 -07003082void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003083{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003084 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003085 ASSERT(buffer);
3086
Geoff Lang496c02d2016-10-20 11:38:11 -07003087 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003088}
3089
3090GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3091{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003092 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003093 ASSERT(buffer);
3094
3095 Error error = buffer->map(access);
3096 if (error.isError())
3097 {
Jamie Madill437fa652016-05-03 15:13:24 -04003098 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003099 return nullptr;
3100 }
3101
3102 return buffer->getMapPointer();
3103}
3104
3105GLboolean Context::unmapBuffer(GLenum target)
3106{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003107 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003108 ASSERT(buffer);
3109
3110 GLboolean result;
3111 Error error = buffer->unmap(&result);
3112 if (error.isError())
3113 {
Jamie Madill437fa652016-05-03 15:13:24 -04003114 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003115 return GL_FALSE;
3116 }
3117
3118 return result;
3119}
3120
3121GLvoid *Context::mapBufferRange(GLenum target,
3122 GLintptr offset,
3123 GLsizeiptr length,
3124 GLbitfield access)
3125{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003126 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003127 ASSERT(buffer);
3128
3129 Error error = buffer->mapRange(offset, length, access);
3130 if (error.isError())
3131 {
Jamie Madill437fa652016-05-03 15:13:24 -04003132 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003133 return nullptr;
3134 }
3135
3136 return buffer->getMapPointer();
3137}
3138
3139void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3140{
3141 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3142}
3143
Jamie Madillad9f24e2016-02-12 09:27:24 -05003144void Context::syncStateForReadPixels()
3145{
3146 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3147}
3148
3149void Context::syncStateForTexImage()
3150{
3151 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3152}
3153
3154void Context::syncStateForClear()
3155{
3156 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3157}
3158
3159void Context::syncStateForBlit()
3160{
3161 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3162}
3163
Jamie Madillc20ab272016-06-09 07:20:46 -07003164void Context::activeTexture(GLenum texture)
3165{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003166 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003167}
3168
3169void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3170{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003171 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003172}
3173
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003174void Context::blendEquation(GLenum mode)
3175{
3176 mGLState.setBlendEquation(mode, mode);
3177}
3178
Jamie Madillc20ab272016-06-09 07:20:46 -07003179void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3180{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003181 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003182}
3183
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003184void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3185{
3186 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3187}
3188
Jamie Madillc20ab272016-06-09 07:20:46 -07003189void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3190{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003191 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003192}
3193
3194void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3195{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003196 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003197}
3198
3199void Context::clearDepthf(GLclampf depth)
3200{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003201 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003202}
3203
3204void Context::clearStencil(GLint s)
3205{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003206 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003207}
3208
3209void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3210{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003211 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003212}
3213
3214void Context::cullFace(GLenum mode)
3215{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003216 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003217}
3218
3219void Context::depthFunc(GLenum func)
3220{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003221 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003222}
3223
3224void Context::depthMask(GLboolean flag)
3225{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003226 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003227}
3228
3229void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3230{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003231 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003232}
3233
3234void Context::disable(GLenum cap)
3235{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003236 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003237}
3238
3239void Context::disableVertexAttribArray(GLuint index)
3240{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003241 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003242}
3243
3244void Context::enable(GLenum cap)
3245{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003246 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003247}
3248
3249void Context::enableVertexAttribArray(GLuint index)
3250{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003251 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003252}
3253
3254void Context::frontFace(GLenum mode)
3255{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003256 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003257}
3258
3259void Context::hint(GLenum target, GLenum mode)
3260{
3261 switch (target)
3262 {
3263 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003264 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003265 break;
3266
3267 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003268 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003269 break;
3270
3271 default:
3272 UNREACHABLE();
3273 return;
3274 }
3275}
3276
3277void Context::lineWidth(GLfloat width)
3278{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003279 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003280}
3281
3282void Context::pixelStorei(GLenum pname, GLint param)
3283{
3284 switch (pname)
3285 {
3286 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003287 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003288 break;
3289
3290 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003291 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003292 break;
3293
3294 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003295 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003296 break;
3297
3298 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003299 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003300 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003301 break;
3302
3303 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003304 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003305 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003306 break;
3307
3308 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003309 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003310 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003311 break;
3312
3313 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003314 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003315 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003316 break;
3317
3318 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003319 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003320 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003321 break;
3322
3323 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003324 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003325 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003326 break;
3327
3328 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003329 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003330 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003331 break;
3332
3333 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003334 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003335 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003336 break;
3337
3338 default:
3339 UNREACHABLE();
3340 return;
3341 }
3342}
3343
3344void Context::polygonOffset(GLfloat factor, GLfloat units)
3345{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003346 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003347}
3348
3349void Context::sampleCoverage(GLclampf value, GLboolean invert)
3350{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003351 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003352}
3353
3354void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3355{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003356 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003357}
3358
3359void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3360{
3361 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3362 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003363 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003364 }
3365
3366 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3367 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003368 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003369 }
3370}
3371
3372void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3373{
3374 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3375 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003376 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003377 }
3378
3379 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3380 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003381 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003382 }
3383}
3384
3385void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3386{
3387 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3388 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003390 }
3391
3392 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3393 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003394 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003395 }
3396}
3397
3398void Context::vertexAttrib1f(GLuint index, GLfloat x)
3399{
3400 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003401 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003402}
3403
3404void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3405{
3406 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003407 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003408}
3409
3410void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3411{
3412 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003414}
3415
3416void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3417{
3418 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420}
3421
3422void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3423{
3424 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003425 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003426}
3427
3428void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3429{
3430 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003431 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003432}
3433
3434void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3435{
3436 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003437 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003438}
3439
3440void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3441{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003442 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003443}
3444
3445void Context::vertexAttribPointer(GLuint index,
3446 GLint size,
3447 GLenum type,
3448 GLboolean normalized,
3449 GLsizei stride,
3450 const GLvoid *ptr)
3451{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003452 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3453 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003454}
3455
3456void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3457{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003458 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003459}
3460
3461void Context::vertexAttribIPointer(GLuint index,
3462 GLint size,
3463 GLenum type,
3464 GLsizei stride,
3465 const GLvoid *pointer)
3466{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003467 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3468 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003469}
3470
3471void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3472{
3473 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003474 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003475}
3476
3477void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3478{
3479 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003480 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003481}
3482
3483void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3484{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003485 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003486}
3487
3488void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3489{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003490 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003491}
3492
3493void Context::debugMessageControl(GLenum source,
3494 GLenum type,
3495 GLenum severity,
3496 GLsizei count,
3497 const GLuint *ids,
3498 GLboolean enabled)
3499{
3500 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003501 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3502 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003503}
3504
3505void Context::debugMessageInsert(GLenum source,
3506 GLenum type,
3507 GLuint id,
3508 GLenum severity,
3509 GLsizei length,
3510 const GLchar *buf)
3511{
3512 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003513 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003514}
3515
3516void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3517{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003518 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003519}
3520
3521GLuint Context::getDebugMessageLog(GLuint count,
3522 GLsizei bufSize,
3523 GLenum *sources,
3524 GLenum *types,
3525 GLuint *ids,
3526 GLenum *severities,
3527 GLsizei *lengths,
3528 GLchar *messageLog)
3529{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003530 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3531 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003532}
3533
3534void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3535{
3536 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003538}
3539
3540void Context::popDebugGroup()
3541{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003542 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003543}
3544
Jamie Madill29639852016-09-02 15:00:09 -04003545void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3546{
3547 Buffer *buffer = mGLState.getTargetBuffer(target);
3548 ASSERT(buffer);
3549 handleError(buffer->bufferData(target, data, size, usage));
3550}
3551
3552void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3553{
3554 if (data == nullptr)
3555 {
3556 return;
3557 }
3558
3559 Buffer *buffer = mGLState.getTargetBuffer(target);
3560 ASSERT(buffer);
3561 handleError(buffer->bufferSubData(target, data, size, offset));
3562}
3563
Jamie Madillef300b12016-10-07 15:12:09 -04003564void Context::attachShader(GLuint program, GLuint shader)
3565{
3566 auto programObject = mResourceManager->getProgram(program);
3567 auto shaderObject = mResourceManager->getShader(shader);
3568 ASSERT(programObject && shaderObject);
3569 programObject->attachShader(shaderObject);
3570}
3571
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003572const Workarounds &Context::getWorkarounds() const
3573{
3574 return mWorkarounds;
3575}
3576
Jamie Madillb0817d12016-11-01 15:48:31 -04003577void Context::copyBufferSubData(GLenum readTarget,
3578 GLenum writeTarget,
3579 GLintptr readOffset,
3580 GLintptr writeOffset,
3581 GLsizeiptr size)
3582{
3583 // if size is zero, the copy is a successful no-op
3584 if (size == 0)
3585 {
3586 return;
3587 }
3588
3589 // TODO(jmadill): cache these.
3590 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3591 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3592
3593 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3594}
3595
Jamie Madill01a80ee2016-11-07 12:06:18 -05003596void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3597{
3598 Program *programObject = getProgram(program);
3599 // TODO(jmadill): Re-use this from the validation if possible.
3600 ASSERT(programObject);
3601 programObject->bindAttributeLocation(index, name);
3602}
3603
3604void Context::bindBuffer(GLenum target, GLuint buffer)
3605{
3606 switch (target)
3607 {
3608 case GL_ARRAY_BUFFER:
3609 bindArrayBuffer(buffer);
3610 break;
3611 case GL_ELEMENT_ARRAY_BUFFER:
3612 bindElementArrayBuffer(buffer);
3613 break;
3614 case GL_COPY_READ_BUFFER:
3615 bindCopyReadBuffer(buffer);
3616 break;
3617 case GL_COPY_WRITE_BUFFER:
3618 bindCopyWriteBuffer(buffer);
3619 break;
3620 case GL_PIXEL_PACK_BUFFER:
3621 bindPixelPackBuffer(buffer);
3622 break;
3623 case GL_PIXEL_UNPACK_BUFFER:
3624 bindPixelUnpackBuffer(buffer);
3625 break;
3626 case GL_UNIFORM_BUFFER:
3627 bindGenericUniformBuffer(buffer);
3628 break;
3629 case GL_TRANSFORM_FEEDBACK_BUFFER:
3630 bindGenericTransformFeedbackBuffer(buffer);
3631 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003632 case GL_ATOMIC_COUNTER_BUFFER:
3633 UNIMPLEMENTED();
3634 break;
3635 case GL_SHADER_STORAGE_BUFFER:
3636 UNIMPLEMENTED();
3637 break;
3638 case GL_DRAW_INDIRECT_BUFFER:
3639 UNIMPLEMENTED();
3640 break;
3641 case GL_DISPATCH_INDIRECT_BUFFER:
3642 UNIMPLEMENTED();
3643 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003644
3645 default:
3646 UNREACHABLE();
3647 break;
3648 }
3649}
3650
3651void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3652{
3653 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3654 {
3655 bindReadFramebuffer(framebuffer);
3656 }
3657
3658 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3659 {
3660 bindDrawFramebuffer(framebuffer);
3661 }
3662}
3663
3664void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3665{
3666 ASSERT(target == GL_RENDERBUFFER);
3667 Renderbuffer *object =
3668 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
3669 mGLState.setRenderbufferBinding(object);
3670}
3671
Jamie Madillc29968b2016-01-20 11:17:23 -05003672} // namespace gl