blob: 38fc9177d61f2e25141ba309dd694e33a7600fe3 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050023#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Fence.h"
25#include "libANGLE/Framebuffer.h"
26#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
37#include "libANGLE/formatutils.h"
38#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070039#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040040#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040041#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030042#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040043#include "libANGLE/queryutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Ian Ewell3ffd78b2016-01-22 16:09:42 -050048template <typename T>
Sami Väisänend59ca052016-06-21 16:10:00 +030049std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
50 GLsizei numPaths,
51 const void *paths,
52 GLuint pathBase)
53{
54 std::vector<gl::Path *> ret;
55 ret.reserve(numPaths);
56
57 const auto *nameArray = static_cast<const T *>(paths);
58
59 for (GLsizei i = 0; i < numPaths; ++i)
60 {
61 const GLuint pathName = nameArray[i] + pathBase;
62
63 ret.push_back(resourceManager.getPath(pathName));
64 }
65
66 return ret;
67}
68
69std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
70 GLsizei numPaths,
71 GLenum pathNameType,
72 const void *paths,
73 GLuint pathBase)
74{
75 switch (pathNameType)
76 {
77 case GL_UNSIGNED_BYTE:
78 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_BYTE:
81 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_UNSIGNED_SHORT:
84 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_SHORT:
87 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_INT:
90 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_INT:
93 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
94 }
95
96 UNREACHABLE();
97 return std::vector<gl::Path *>();
98}
99
100template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400101gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500102{
Geoff Lang2186c382016-10-14 10:54:54 -0400103 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500104
105 switch (pname)
106 {
107 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400108 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109 case GL_QUERY_RESULT_AVAILABLE_EXT:
110 {
111 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400112 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500113 if (!error.isError())
114 {
Geoff Lang2186c382016-10-14 10:54:54 -0400115 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500116 }
117 return error;
118 }
119 default:
120 UNREACHABLE();
121 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
122 }
123}
124
Geoff Langf6db0982015-08-25 13:04:00 -0400125void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
126{
Geoff Lang1a683462015-09-29 15:09:59 -0400127 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400128 {
129 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
130 tfBufferIndex++)
131 {
132 const OffsetBindingPointer<gl::Buffer> &buffer =
133 transformFeedback->getIndexedBuffer(tfBufferIndex);
134 if (buffer.get() != nullptr)
135 {
136 buffer->onTransformFeedback();
137 }
138 }
139 }
140}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141
142// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300143EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400145 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146}
147
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
149{
150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
151}
152
Geoff Langeb66a6e2016-10-31 13:06:12 -0400153gl::Version GetClientVersion(const egl::AttributeMap &attribs)
154{
155 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
156}
157
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500158GLenum GetResetStrategy(const egl::AttributeMap &attribs)
159{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400160 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
161 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500162 switch (attrib)
163 {
164 case EGL_NO_RESET_NOTIFICATION:
165 return GL_NO_RESET_NOTIFICATION_EXT;
166 case EGL_LOSE_CONTEXT_ON_RESET:
167 return GL_LOSE_CONTEXT_ON_RESET_EXT;
168 default:
169 UNREACHABLE();
170 return GL_NONE;
171 }
172}
173
174bool GetRobustAccess(const egl::AttributeMap &attribs)
175{
Geoff Lang077f20a2016-11-01 10:08:02 -0400176 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
177 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
178 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500179}
180
181bool GetDebug(const egl::AttributeMap &attribs)
182{
Geoff Lang077f20a2016-11-01 10:08:02 -0400183 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
184 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetNoError(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
190}
191
Geoff Langc287ea62016-09-16 14:46:51 -0400192bool GetWebGLContext(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langf41a7152016-09-19 15:11:17 -0400197bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
200}
201
Martin Radev9d901792016-07-15 15:58:58 +0300202std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
203{
204 std::string labelName;
205 if (label != nullptr)
206 {
207 size_t labelLength = length < 0 ? strlen(label) : length;
208 labelName = std::string(label, labelLength);
209 }
210 return labelName;
211}
212
213void GetObjectLabelBase(const std::string &objectLabel,
214 GLsizei bufSize,
215 GLsizei *length,
216 GLchar *label)
217{
218 size_t writeLength = objectLabel.length();
219 if (label != nullptr && bufSize > 0)
220 {
221 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
222 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
223 label[writeLength] = '\0';
224 }
225
226 if (length != nullptr)
227 {
228 *length = static_cast<GLsizei>(writeLength);
229 }
230}
231
Geoff Langf6db0982015-08-25 13:04:00 -0400232} // anonymous namespace
233
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000234namespace gl
235{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000236
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400237Context::Context(rx::EGLImplFactory *implFactory,
238 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400239 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500240 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300241
Geoff Langeb66a6e2016-10-31 13:06:12 -0400242 : ValidationContext(GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700243 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500244 mCaps,
245 mTextureCaps,
246 mExtensions,
247 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500248 mLimitations,
Jamie Madill01a80ee2016-11-07 12:06:18 -0500249 mFramebufferMap,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500250 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700251 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500252 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400253 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500254 mClientType(EGL_OPENGL_ES_API),
255 mHasBeenCurrent(false),
256 mContextLost(false),
257 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700258 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500259 mResetStrategy(GetResetStrategy(attribs)),
260 mRobustAccess(GetRobustAccess(attribs)),
261 mCurrentSurface(nullptr),
262 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000263{
Geoff Lang077f20a2016-11-01 10:08:02 -0400264 if (mRobustAccess)
265 {
266 UNIMPLEMENTED();
267 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000268
Geoff Langc287ea62016-09-16 14:46:51 -0400269 initCaps(GetWebGLContext(attribs));
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700270 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400271
Geoff Langeb66a6e2016-10-31 13:06:12 -0400272 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400273 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100274
Shannon Woods53a94a82014-06-24 15:20:36 -0400275 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400276
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400277 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000278 {
279 mResourceManager = shareContext->mResourceManager;
280 mResourceManager->addRef();
281 }
282 else
283 {
Jamie Madill901b3792016-05-26 09:20:40 -0400284 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000285 }
286
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700287 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400288
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000289 // [OpenGL ES 2.0.24] section 3.7 page 83:
290 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
291 // and cube map texture state vectors respectively associated with them.
292 // In order that access to these initial textures not be lost, they are treated as texture
293 // objects all of whose names are 0.
294
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400295 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500296 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500297
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400298 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400300
Geoff Langeb66a6e2016-10-31 13:06:12 -0400301 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400302 {
303 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400304 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500305 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400306
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500308 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400309 }
Geoff Lang3b573612016-10-31 14:08:10 -0400310 if (getClientVersion() >= Version(3, 1))
311 {
312 Texture *zeroTexture2DMultisample =
313 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
314 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
315 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000316
Ian Ewellbda75592016-04-18 17:25:54 -0400317 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
318 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400319 Texture *zeroTextureExternal =
320 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400321 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
322 }
323
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700324 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500325
Jamie Madill57a89722013-07-02 11:57:03 -0400326 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000327 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800328 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000329 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400330
Jamie Madill01a80ee2016-11-07 12:06:18 -0500331 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000332
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000333 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500334 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000335 {
336 bindIndexedUniformBuffer(0, i, 0, -1);
337 }
338
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000339 bindCopyReadBuffer(0);
340 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000341 bindPixelPackBuffer(0);
342 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000343
Geoff Langeb66a6e2016-10-31 13:06:12 -0400344 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400345 {
346 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
347 // In the initial state, a default transform feedback object is bound and treated as
348 // a transform feedback object with a name of zero. That object is bound any time
349 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400350 bindTransformFeedback(0);
351 }
Geoff Langc8058452014-02-03 12:04:11 -0500352
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700353 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500354
355 // Initialize dirty bit masks
356 // TODO(jmadill): additional ES3 state
357 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
358 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
359 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
360 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
361 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
362 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400363 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500364 // No dirty objects.
365
366 // Readpixels uses the pack state and read FBO
367 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
368 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
369 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
370 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
371 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400372 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500373 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
374
375 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
376 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
377 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
378 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
379 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
380 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
381 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
382 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
383 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
384 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
385 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
386 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
387
388 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
389 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700390 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500391 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
392 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400393
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400394 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395}
396
397Context::~Context()
398{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700399 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000400
Corentin Wallez37c39792015-08-20 14:19:46 -0400401 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000402 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400403 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400404 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400405 {
406 SafeDelete(framebuffer.second);
407 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000408 }
409
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000411 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400412 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000413 }
414
Corentin Wallez80b24112015-08-25 16:41:57 -0400415 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000416 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400417 if (query.second != nullptr)
418 {
419 query.second->release();
420 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421 }
422
Corentin Wallez80b24112015-08-25 16:41:57 -0400423 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400424 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400425 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400426 }
427
Corentin Wallez80b24112015-08-25 16:41:57 -0400428 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500429 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500430 if (transformFeedback.second != nullptr)
431 {
432 transformFeedback.second->release();
433 }
Geoff Langc8058452014-02-03 12:04:11 -0500434 }
435
Jamie Madilldedd7b92014-11-05 16:30:36 -0500436 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400437 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500438 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400439 }
440 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000441
Corentin Wallez51706ea2015-08-07 14:39:22 -0400442 if (mCurrentSurface != nullptr)
443 {
444 releaseSurface();
445 }
446
Jamie Madill1e9ae072014-11-06 15:27:21 -0500447 if (mResourceManager)
448 {
449 mResourceManager->release();
450 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500451
452 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000453}
454
daniel@transgaming.comad629872012-11-28 19:32:06 +0000455void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000456{
Jamie Madill77a72f62015-04-14 11:18:32 -0400457 ASSERT(surface != nullptr);
458
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000459 if (!mHasBeenCurrent)
460 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000461 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500462 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400463 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000464
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700465 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
466 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000467
468 mHasBeenCurrent = true;
469 }
470
Jamie Madill1b94d432015-08-07 13:23:23 -0400471 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700472 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400473
Corentin Wallez51706ea2015-08-07 14:39:22 -0400474 if (mCurrentSurface)
475 {
476 releaseSurface();
477 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000478 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400479 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000480
Corentin Wallez37c39792015-08-20 14:19:46 -0400481 // Update default framebuffer, the binding of the previous default
482 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400483 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400484 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700485 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400486 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700487 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400488 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700489 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400490 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700491 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400492 }
493 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400494 }
Ian Ewell292f0052016-02-04 10:37:32 -0500495
496 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700497 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000498}
499
Jamie Madill77a72f62015-04-14 11:18:32 -0400500void Context::releaseSurface()
501{
Corentin Wallez37c39792015-08-20 14:19:46 -0400502 ASSERT(mCurrentSurface != nullptr);
503
504 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400505 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400506 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700507 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400508 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700509 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400510 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700511 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400512 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700513 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400514 }
515 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400516 }
517
Corentin Wallez51706ea2015-08-07 14:39:22 -0400518 mCurrentSurface->setIsCurrent(false);
519 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400520}
521
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000522GLuint Context::createBuffer()
523{
524 return mResourceManager->createBuffer();
525}
526
527GLuint Context::createProgram()
528{
Jamie Madill901b3792016-05-26 09:20:40 -0400529 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000530}
531
532GLuint Context::createShader(GLenum type)
533{
Jamie Madill901b3792016-05-26 09:20:40 -0400534 return mResourceManager->createShader(mImplementation.get(),
535 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000536}
537
538GLuint Context::createTexture()
539{
540 return mResourceManager->createTexture();
541}
542
543GLuint Context::createRenderbuffer()
544{
545 return mResourceManager->createRenderbuffer();
546}
547
Geoff Lang882033e2014-09-30 11:26:07 -0400548GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400549{
Jamie Madill901b3792016-05-26 09:20:40 -0400550 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400551
Cooper Partind8e62a32015-01-29 15:21:25 -0800552 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400553}
554
Sami Väisänene45e53b2016-05-25 10:36:04 +0300555GLuint Context::createPaths(GLsizei range)
556{
557 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
558 if (resultOrError.isError())
559 {
560 handleError(resultOrError.getError());
561 return 0;
562 }
563 return resultOrError.getResult();
564}
565
Jamie Madill57a89722013-07-02 11:57:03 -0400566GLuint Context::createVertexArray()
567{
Geoff Lang36167ab2015-12-07 10:27:14 -0500568 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
569 mVertexArrayMap[vertexArray] = nullptr;
570 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400571}
572
Jamie Madilldc356042013-07-19 16:36:57 -0400573GLuint Context::createSampler()
574{
575 return mResourceManager->createSampler();
576}
577
Geoff Langc8058452014-02-03 12:04:11 -0500578GLuint Context::createTransformFeedback()
579{
Geoff Lang36167ab2015-12-07 10:27:14 -0500580 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
581 mTransformFeedbackMap[transformFeedback] = nullptr;
582 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500583}
584
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585// Returns an unused framebuffer name
586GLuint Context::createFramebuffer()
587{
588 GLuint handle = mFramebufferHandleAllocator.allocate();
589
590 mFramebufferMap[handle] = NULL;
591
592 return handle;
593}
594
Jamie Madill33dc8432013-07-26 11:55:05 -0400595GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000596{
Jamie Madill33dc8432013-07-26 11:55:05 -0400597 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000598
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400599 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000600
601 return handle;
602}
603
604// Returns an unused query name
605GLuint Context::createQuery()
606{
607 GLuint handle = mQueryHandleAllocator.allocate();
608
609 mQueryMap[handle] = NULL;
610
611 return handle;
612}
613
614void Context::deleteBuffer(GLuint buffer)
615{
616 if (mResourceManager->getBuffer(buffer))
617 {
618 detachBuffer(buffer);
619 }
Jamie Madill893ab082014-05-16 16:56:10 -0400620
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000621 mResourceManager->deleteBuffer(buffer);
622}
623
624void Context::deleteShader(GLuint shader)
625{
626 mResourceManager->deleteShader(shader);
627}
628
629void Context::deleteProgram(GLuint program)
630{
631 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000632}
633
634void Context::deleteTexture(GLuint texture)
635{
636 if (mResourceManager->getTexture(texture))
637 {
638 detachTexture(texture);
639 }
640
641 mResourceManager->deleteTexture(texture);
642}
643
644void Context::deleteRenderbuffer(GLuint renderbuffer)
645{
646 if (mResourceManager->getRenderbuffer(renderbuffer))
647 {
648 detachRenderbuffer(renderbuffer);
649 }
Jamie Madill893ab082014-05-16 16:56:10 -0400650
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651 mResourceManager->deleteRenderbuffer(renderbuffer);
652}
653
Jamie Madillcd055f82013-07-26 11:55:15 -0400654void Context::deleteFenceSync(GLsync fenceSync)
655{
656 // The spec specifies the underlying Fence object is not deleted until all current
657 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
658 // and since our API is currently designed for being called from a single thread, we can delete
659 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700660 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400661}
662
Sami Väisänene45e53b2016-05-25 10:36:04 +0300663void Context::deletePaths(GLuint first, GLsizei range)
664{
665 mResourceManager->deletePaths(first, range);
666}
667
668bool Context::hasPathData(GLuint path) const
669{
670 const auto *pathObj = mResourceManager->getPath(path);
671 if (pathObj == nullptr)
672 return false;
673
674 return pathObj->hasPathData();
675}
676
677bool Context::hasPath(GLuint path) const
678{
679 return mResourceManager->hasPath(path);
680}
681
682void Context::setPathCommands(GLuint path,
683 GLsizei numCommands,
684 const GLubyte *commands,
685 GLsizei numCoords,
686 GLenum coordType,
687 const void *coords)
688{
689 auto *pathObject = mResourceManager->getPath(path);
690
691 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
692}
693
694void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
695{
696 auto *pathObj = mResourceManager->getPath(path);
697
698 switch (pname)
699 {
700 case GL_PATH_STROKE_WIDTH_CHROMIUM:
701 pathObj->setStrokeWidth(value);
702 break;
703 case GL_PATH_END_CAPS_CHROMIUM:
704 pathObj->setEndCaps(static_cast<GLenum>(value));
705 break;
706 case GL_PATH_JOIN_STYLE_CHROMIUM:
707 pathObj->setJoinStyle(static_cast<GLenum>(value));
708 break;
709 case GL_PATH_MITER_LIMIT_CHROMIUM:
710 pathObj->setMiterLimit(value);
711 break;
712 case GL_PATH_STROKE_BOUND_CHROMIUM:
713 pathObj->setStrokeBound(value);
714 break;
715 default:
716 UNREACHABLE();
717 break;
718 }
719}
720
721void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
722{
723 const auto *pathObj = mResourceManager->getPath(path);
724
725 switch (pname)
726 {
727 case GL_PATH_STROKE_WIDTH_CHROMIUM:
728 *value = pathObj->getStrokeWidth();
729 break;
730 case GL_PATH_END_CAPS_CHROMIUM:
731 *value = static_cast<GLfloat>(pathObj->getEndCaps());
732 break;
733 case GL_PATH_JOIN_STYLE_CHROMIUM:
734 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
735 break;
736 case GL_PATH_MITER_LIMIT_CHROMIUM:
737 *value = pathObj->getMiterLimit();
738 break;
739 case GL_PATH_STROKE_BOUND_CHROMIUM:
740 *value = pathObj->getStrokeBound();
741 break;
742 default:
743 UNREACHABLE();
744 break;
745 }
746}
747
748void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
749{
750 mGLState.setPathStencilFunc(func, ref, mask);
751}
752
Jamie Madill57a89722013-07-02 11:57:03 -0400753void Context::deleteVertexArray(GLuint vertexArray)
754{
Geoff Lang36167ab2015-12-07 10:27:14 -0500755 auto iter = mVertexArrayMap.find(vertexArray);
756 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000757 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500758 VertexArray *vertexArrayObject = iter->second;
759 if (vertexArrayObject != nullptr)
760 {
761 detachVertexArray(vertexArray);
762 delete vertexArrayObject;
763 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000764
Geoff Lang36167ab2015-12-07 10:27:14 -0500765 mVertexArrayMap.erase(iter);
766 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400767 }
768}
769
Jamie Madilldc356042013-07-19 16:36:57 -0400770void Context::deleteSampler(GLuint sampler)
771{
772 if (mResourceManager->getSampler(sampler))
773 {
774 detachSampler(sampler);
775 }
776
777 mResourceManager->deleteSampler(sampler);
778}
779
Geoff Langc8058452014-02-03 12:04:11 -0500780void Context::deleteTransformFeedback(GLuint transformFeedback)
781{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500782 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500783 if (iter != mTransformFeedbackMap.end())
784 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500785 TransformFeedback *transformFeedbackObject = iter->second;
786 if (transformFeedbackObject != nullptr)
787 {
788 detachTransformFeedback(transformFeedback);
789 transformFeedbackObject->release();
790 }
791
Geoff Lang50b3fe82015-12-08 14:49:12 +0000792 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500793 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500794 }
795}
796
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000797void Context::deleteFramebuffer(GLuint framebuffer)
798{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500799 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800
801 if (framebufferObject != mFramebufferMap.end())
802 {
803 detachFramebuffer(framebuffer);
804
805 mFramebufferHandleAllocator.release(framebufferObject->first);
806 delete framebufferObject->second;
807 mFramebufferMap.erase(framebufferObject);
808 }
809}
810
Jamie Madill33dc8432013-07-26 11:55:05 -0400811void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000812{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500813 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000814
Jamie Madill33dc8432013-07-26 11:55:05 -0400815 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400817 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000818 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400819 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820 }
821}
822
823void Context::deleteQuery(GLuint query)
824{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500825 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000826 if (queryObject != mQueryMap.end())
827 {
828 mQueryHandleAllocator.release(queryObject->first);
829 if (queryObject->second)
830 {
831 queryObject->second->release();
832 }
833 mQueryMap.erase(queryObject);
834 }
835}
836
Geoff Lang70d0f492015-12-10 17:45:46 -0500837Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000838{
839 return mResourceManager->getBuffer(handle);
840}
841
Jamie Madill570f7c82014-07-03 10:38:54 -0400842Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843{
844 return mResourceManager->getTexture(handle);
845}
846
Geoff Lang70d0f492015-12-10 17:45:46 -0500847Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000848{
849 return mResourceManager->getRenderbuffer(handle);
850}
851
Jamie Madillcd055f82013-07-26 11:55:15 -0400852FenceSync *Context::getFenceSync(GLsync handle) const
853{
Minmin Gong794e0002015-04-07 18:31:54 -0700854 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400855}
856
Jamie Madill57a89722013-07-02 11:57:03 -0400857VertexArray *Context::getVertexArray(GLuint handle) const
858{
859 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500860 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400861}
862
Jamie Madilldc356042013-07-19 16:36:57 -0400863Sampler *Context::getSampler(GLuint handle) const
864{
865 return mResourceManager->getSampler(handle);
866}
867
Geoff Langc8058452014-02-03 12:04:11 -0500868TransformFeedback *Context::getTransformFeedback(GLuint handle) const
869{
Geoff Lang36167ab2015-12-07 10:27:14 -0500870 auto iter = mTransformFeedbackMap.find(handle);
871 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500872}
873
Geoff Lang70d0f492015-12-10 17:45:46 -0500874LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
875{
876 switch (identifier)
877 {
878 case GL_BUFFER:
879 return getBuffer(name);
880 case GL_SHADER:
881 return getShader(name);
882 case GL_PROGRAM:
883 return getProgram(name);
884 case GL_VERTEX_ARRAY:
885 return getVertexArray(name);
886 case GL_QUERY:
887 return getQuery(name);
888 case GL_TRANSFORM_FEEDBACK:
889 return getTransformFeedback(name);
890 case GL_SAMPLER:
891 return getSampler(name);
892 case GL_TEXTURE:
893 return getTexture(name);
894 case GL_RENDERBUFFER:
895 return getRenderbuffer(name);
896 case GL_FRAMEBUFFER:
897 return getFramebuffer(name);
898 default:
899 UNREACHABLE();
900 return nullptr;
901 }
902}
903
904LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
905{
906 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
907}
908
Martin Radev9d901792016-07-15 15:58:58 +0300909void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
910{
911 LabeledObject *object = getLabeledObject(identifier, name);
912 ASSERT(object != nullptr);
913
914 std::string labelName = GetObjectLabelFromPointer(length, label);
915 object->setLabel(labelName);
916}
917
918void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
919{
920 LabeledObject *object = getLabeledObjectFromPtr(ptr);
921 ASSERT(object != nullptr);
922
923 std::string labelName = GetObjectLabelFromPointer(length, label);
924 object->setLabel(labelName);
925}
926
927void Context::getObjectLabel(GLenum identifier,
928 GLuint name,
929 GLsizei bufSize,
930 GLsizei *length,
931 GLchar *label) const
932{
933 LabeledObject *object = getLabeledObject(identifier, name);
934 ASSERT(object != nullptr);
935
936 const std::string &objectLabel = object->getLabel();
937 GetObjectLabelBase(objectLabel, bufSize, length, label);
938}
939
940void Context::getObjectPtrLabel(const void *ptr,
941 GLsizei bufSize,
942 GLsizei *length,
943 GLchar *label) const
944{
945 LabeledObject *object = getLabeledObjectFromPtr(ptr);
946 ASSERT(object != nullptr);
947
948 const std::string &objectLabel = object->getLabel();
949 GetObjectLabelBase(objectLabel, bufSize, length, label);
950}
951
Jamie Madilldc356042013-07-19 16:36:57 -0400952bool Context::isSampler(GLuint samplerName) const
953{
954 return mResourceManager->isSampler(samplerName);
955}
956
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500957void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958{
Jamie Madill901b3792016-05-26 09:20:40 -0400959 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700960 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000961}
962
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800963void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
964{
965 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
966 mGLState.setDrawIndirectBufferBinding(buffer);
967}
968
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500969void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000970{
Jamie Madill901b3792016-05-26 09:20:40 -0400971 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700972 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000973}
974
Jamie Madilldedd7b92014-11-05 16:30:36 -0500975void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500977 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978
Jamie Madilldedd7b92014-11-05 16:30:36 -0500979 if (handle == 0)
980 {
981 texture = mZeroTextures[target].get();
982 }
983 else
984 {
Jamie Madill901b3792016-05-26 09:20:40 -0400985 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500986 }
987
988 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700989 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000990}
991
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500992void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500994 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700995 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996}
997
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500998void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001000 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001001 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001002}
1003
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001004void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001005{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001006 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001007 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001008}
1009
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001010void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001011{
Geoff Lang76b10c92014-09-05 16:28:14 -04001012 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001013 Sampler *sampler =
1014 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001015 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001016}
1017
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001018void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001019{
Jamie Madill901b3792016-05-26 09:20:40 -04001020 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001022}
1023
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1025 GLuint index,
1026 GLintptr offset,
1027 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001028{
Jamie Madill901b3792016-05-26 09:20:40 -04001029 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001030 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001031}
1032
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001033void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001034{
Jamie Madill901b3792016-05-26 09:20:40 -04001035 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001036 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001037}
1038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1040 GLuint index,
1041 GLintptr offset,
1042 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001043{
Jamie Madill901b3792016-05-26 09:20:40 -04001044 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001045 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001046}
1047
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001048void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001049{
Jamie Madill901b3792016-05-26 09:20:40 -04001050 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001051 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001052}
1053
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001054void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001055{
Jamie Madill901b3792016-05-26 09:20:40 -04001056 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001057 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001061{
Jamie Madill901b3792016-05-26 09:20:40 -04001062 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001067{
Jamie Madill901b3792016-05-26 09:20:40 -04001068 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001069 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001070}
1071
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001072void Context::useProgram(GLuint program)
1073{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001074 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001075}
1076
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001077void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001078{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001079 TransformFeedback *transformFeedback =
1080 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001081 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001082}
1083
Geoff Lang5aad9672014-09-08 11:10:42 -04001084Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001086 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001087 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088
Geoff Lang5aad9672014-09-08 11:10:42 -04001089 // begin query
1090 Error error = queryObject->begin();
1091 if (error.isError())
1092 {
1093 return error;
1094 }
1095
1096 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001097 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001098
Geoff Lang5aad9672014-09-08 11:10:42 -04001099 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001100}
1101
Geoff Lang5aad9672014-09-08 11:10:42 -04001102Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001103{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001104 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001105 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106
Geoff Lang5aad9672014-09-08 11:10:42 -04001107 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001108
Geoff Lang5aad9672014-09-08 11:10:42 -04001109 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001110 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001111
1112 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001113}
1114
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001115Error Context::queryCounter(GLuint id, GLenum target)
1116{
1117 ASSERT(target == GL_TIMESTAMP_EXT);
1118
1119 Query *queryObject = getQuery(id, true, target);
1120 ASSERT(queryObject);
1121
1122 return queryObject->queryCounter();
1123}
1124
1125void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1126{
1127 switch (pname)
1128 {
1129 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001130 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001131 break;
1132 case GL_QUERY_COUNTER_BITS_EXT:
1133 switch (target)
1134 {
1135 case GL_TIME_ELAPSED_EXT:
1136 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1137 break;
1138 case GL_TIMESTAMP_EXT:
1139 params[0] = getExtensions().queryCounterBitsTimestamp;
1140 break;
1141 default:
1142 UNREACHABLE();
1143 params[0] = 0;
1144 break;
1145 }
1146 break;
1147 default:
1148 UNREACHABLE();
1149 return;
1150 }
1151}
1152
Geoff Lang2186c382016-10-14 10:54:54 -04001153void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001154{
Geoff Lang2186c382016-10-14 10:54:54 -04001155 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001156}
1157
Geoff Lang2186c382016-10-14 10:54:54 -04001158void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001159{
Geoff Lang2186c382016-10-14 10:54:54 -04001160 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001161}
1162
Geoff Lang2186c382016-10-14 10:54:54 -04001163void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001164{
Geoff Lang2186c382016-10-14 10:54:54 -04001165 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001166}
1167
Geoff Lang2186c382016-10-14 10:54:54 -04001168void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001169{
Geoff Lang2186c382016-10-14 10:54:54 -04001170 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001171}
1172
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001173Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001175 auto framebufferIt = mFramebufferMap.find(handle);
1176 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177}
1178
Jamie Madill33dc8432013-07-26 11:55:05 -04001179FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001181 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001182
Jamie Madill33dc8432013-07-26 11:55:05 -04001183 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184 {
1185 return NULL;
1186 }
1187 else
1188 {
1189 return fence->second;
1190 }
1191}
1192
1193Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1194{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001195 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001196
1197 if (query == mQueryMap.end())
1198 {
1199 return NULL;
1200 }
1201 else
1202 {
1203 if (!query->second && create)
1204 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001205 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206 query->second->addRef();
1207 }
1208 return query->second;
1209 }
1210}
1211
Geoff Lang70d0f492015-12-10 17:45:46 -05001212Query *Context::getQuery(GLuint handle) const
1213{
1214 auto iter = mQueryMap.find(handle);
1215 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1216}
1217
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001218Texture *Context::getTargetTexture(GLenum target) const
1219{
Ian Ewellbda75592016-04-18 17:25:54 -04001220 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001221 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001222}
1223
Geoff Lang76b10c92014-09-05 16:28:14 -04001224Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001226 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001227}
1228
Geoff Lang492a7e42014-11-05 13:27:06 -05001229Compiler *Context::getCompiler() const
1230{
1231 return mCompiler;
1232}
1233
Jamie Madill893ab082014-05-16 16:56:10 -04001234void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235{
1236 switch (pname)
1237 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001238 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001239 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001241 mGLState.getBooleanv(pname, params);
1242 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244}
1245
Jamie Madill893ab082014-05-16 16:56:10 -04001246void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001247{
Shannon Woods53a94a82014-06-24 15:20:36 -04001248 // Queries about context capabilities and maximums are answered by Context.
1249 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250 switch (pname)
1251 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001252 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001253 params[0] = mCaps.minAliasedLineWidth;
1254 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255 break;
1256 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001257 params[0] = mCaps.minAliasedPointSize;
1258 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001259 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001260 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001261 ASSERT(mExtensions.textureFilterAnisotropic);
1262 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001263 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001264 case GL_MAX_TEXTURE_LOD_BIAS:
1265 *params = mCaps.maxLODBias;
1266 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001267
1268 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1269 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1270 {
1271 ASSERT(mExtensions.pathRendering);
1272 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1273 memcpy(params, m, 16 * sizeof(GLfloat));
1274 }
1275 break;
1276
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001278 mGLState.getFloatv(pname, params);
1279 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281}
1282
Jamie Madill893ab082014-05-16 16:56:10 -04001283void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284{
Shannon Woods53a94a82014-06-24 15:20:36 -04001285 // Queries about context capabilities and maximums are answered by Context.
1286 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001287
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001288 switch (pname)
1289 {
Geoff Lang301d1612014-07-09 10:34:37 -04001290 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1291 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1292 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001293 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1294 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1295 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001296 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1297 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1298 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001299 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001300 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1301 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1302 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001303 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001304 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001305 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1306 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1307 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1308 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001309 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1310 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001311 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1312 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001313 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001314 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1315 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1316 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1317 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001318 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001319 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001320 break;
1321 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001322 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001323 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001324 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1325 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001326 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1327 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1328 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001329 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1330 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1331 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001332 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001333 case GL_MAX_VIEWPORT_DIMS:
1334 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001335 params[0] = mCaps.maxViewportWidth;
1336 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001337 }
1338 break;
1339 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001340 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001341 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001342 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1343 *params = mResetStrategy;
1344 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001345 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001346 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001347 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001348 case GL_SHADER_BINARY_FORMATS:
1349 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1350 break;
1351 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001352 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001353 break;
1354 case GL_PROGRAM_BINARY_FORMATS:
1355 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001356 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001357 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001358 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001359 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001360
1361 // GL_KHR_debug
1362 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1363 *params = mExtensions.maxDebugMessageLength;
1364 break;
1365 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1366 *params = mExtensions.maxDebugLoggedMessages;
1367 break;
1368 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1369 *params = mExtensions.maxDebugGroupStackDepth;
1370 break;
1371 case GL_MAX_LABEL_LENGTH:
1372 *params = mExtensions.maxLabelLength;
1373 break;
1374
Ian Ewell53f59f42016-01-28 17:36:55 -05001375 // GL_EXT_disjoint_timer_query
1376 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001377 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001378 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001379 case GL_MAX_FRAMEBUFFER_WIDTH:
1380 *params = mCaps.maxFramebufferWidth;
1381 break;
1382 case GL_MAX_FRAMEBUFFER_HEIGHT:
1383 *params = mCaps.maxFramebufferHeight;
1384 break;
1385 case GL_MAX_FRAMEBUFFER_SAMPLES:
1386 *params = mCaps.maxFramebufferSamples;
1387 break;
1388 case GL_MAX_SAMPLE_MASK_WORDS:
1389 *params = mCaps.maxSampleMaskWords;
1390 break;
1391 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1392 *params = mCaps.maxColorTextureSamples;
1393 break;
1394 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1395 *params = mCaps.maxDepthTextureSamples;
1396 break;
1397 case GL_MAX_INTEGER_SAMPLES:
1398 *params = mCaps.maxIntegerSamples;
1399 break;
1400 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1401 *params = mCaps.maxVertexAttribRelativeOffset;
1402 break;
1403 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1404 *params = mCaps.maxVertexAttribBindings;
1405 break;
1406 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1407 *params = mCaps.maxVertexAttribStride;
1408 break;
1409 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1410 *params = mCaps.maxVertexAtomicCounterBuffers;
1411 break;
1412 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1413 *params = mCaps.maxVertexAtomicCounters;
1414 break;
1415 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1416 *params = mCaps.maxVertexImageUniforms;
1417 break;
1418 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1419 *params = mCaps.maxVertexShaderStorageBlocks;
1420 break;
1421 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1422 *params = mCaps.maxFragmentAtomicCounterBuffers;
1423 break;
1424 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1425 *params = mCaps.maxFragmentAtomicCounters;
1426 break;
1427 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1428 *params = mCaps.maxFragmentImageUniforms;
1429 break;
1430 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1431 *params = mCaps.maxFragmentShaderStorageBlocks;
1432 break;
1433 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1434 *params = mCaps.minProgramTextureGatherOffset;
1435 break;
1436 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1437 *params = mCaps.maxProgramTextureGatherOffset;
1438 break;
1439 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1440 *params = mCaps.maxComputeWorkGroupInvocations;
1441 break;
1442 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1443 *params = mCaps.maxComputeUniformBlocks;
1444 break;
1445 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1446 *params = mCaps.maxComputeTextureImageUnits;
1447 break;
1448 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1449 *params = mCaps.maxComputeSharedMemorySize;
1450 break;
1451 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1452 *params = mCaps.maxComputeUniformComponents;
1453 break;
1454 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1455 *params = mCaps.maxComputeAtomicCounterBuffers;
1456 break;
1457 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1458 *params = mCaps.maxComputeAtomicCounters;
1459 break;
1460 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1461 *params = mCaps.maxComputeImageUniforms;
1462 break;
1463 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1464 *params = mCaps.maxCombinedComputeUniformComponents;
1465 break;
1466 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1467 *params = mCaps.maxComputeShaderStorageBlocks;
1468 break;
1469 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1470 *params = mCaps.maxCombinedShaderOutputResources;
1471 break;
1472 case GL_MAX_UNIFORM_LOCATIONS:
1473 *params = mCaps.maxUniformLocations;
1474 break;
1475 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1476 *params = mCaps.maxAtomicCounterBufferBindings;
1477 break;
1478 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1479 *params = mCaps.maxAtomicCounterBufferSize;
1480 break;
1481 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1482 *params = mCaps.maxCombinedAtomicCounterBuffers;
1483 break;
1484 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1485 *params = mCaps.maxCombinedAtomicCounters;
1486 break;
1487 case GL_MAX_IMAGE_UNITS:
1488 *params = mCaps.maxImageUnits;
1489 break;
1490 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1491 *params = mCaps.maxCombinedImageUniforms;
1492 break;
1493 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1494 *params = mCaps.maxShaderStorageBufferBindings;
1495 break;
1496 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1497 *params = mCaps.maxCombinedShaderStorageBlocks;
1498 break;
1499 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1500 *params = mCaps.shaderStorageBufferOffsetAlignment;
1501 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001502 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001503 mGLState.getIntegerv(mState, pname, params);
1504 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001505 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001506}
1507
Jamie Madill893ab082014-05-16 16:56:10 -04001508void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001509{
Shannon Woods53a94a82014-06-24 15:20:36 -04001510 // Queries about context capabilities and maximums are answered by Context.
1511 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001512 switch (pname)
1513 {
1514 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001515 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001516 break;
1517 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001518 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001519 break;
1520 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001521 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001522 break;
1523 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001524 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001525 break;
1526 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001527 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001528 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001529
1530 // GL_EXT_disjoint_timer_query
1531 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001532 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001533 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001534
1535 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1536 *params = mCaps.maxShaderStorageBlockSize;
1537 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001538 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001539 UNREACHABLE();
1540 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001541 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001542}
1543
Geoff Lang70d0f492015-12-10 17:45:46 -05001544void Context::getPointerv(GLenum pname, void **params) const
1545{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001546 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001547}
1548
Martin Radev66fb8202016-07-28 11:45:20 +03001549void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001550{
Shannon Woods53a94a82014-06-24 15:20:36 -04001551 // Queries about context capabilities and maximums are answered by Context.
1552 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001553
1554 GLenum nativeType;
1555 unsigned int numParams;
1556 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1557 ASSERT(queryStatus);
1558
1559 if (nativeType == GL_INT)
1560 {
1561 switch (target)
1562 {
1563 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1564 ASSERT(index < 3u);
1565 *data = mCaps.maxComputeWorkGroupCount[index];
1566 break;
1567 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1568 ASSERT(index < 3u);
1569 *data = mCaps.maxComputeWorkGroupSize[index];
1570 break;
1571 default:
1572 mGLState.getIntegeri_v(target, index, data);
1573 }
1574 }
1575 else
1576 {
1577 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1578 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001579}
1580
Martin Radev66fb8202016-07-28 11:45:20 +03001581void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001582{
Shannon Woods53a94a82014-06-24 15:20:36 -04001583 // Queries about context capabilities and maximums are answered by Context.
1584 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001585
1586 GLenum nativeType;
1587 unsigned int numParams;
1588 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1589 ASSERT(queryStatus);
1590
1591 if (nativeType == GL_INT_64_ANGLEX)
1592 {
1593 mGLState.getInteger64i_v(target, index, data);
1594 }
1595 else
1596 {
1597 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1598 }
1599}
1600
1601void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1602{
1603 // Queries about context capabilities and maximums are answered by Context.
1604 // Queries about current GL state values are answered by State.
1605
1606 GLenum nativeType;
1607 unsigned int numParams;
1608 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1609 ASSERT(queryStatus);
1610
1611 if (nativeType == GL_BOOL)
1612 {
1613 mGLState.getBooleani_v(target, index, data);
1614 }
1615 else
1616 {
1617 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1618 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001619}
1620
Geoff Langf6db0982015-08-25 13:04:00 -04001621Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001622{
Jamie Madill1b94d432015-08-07 13:23:23 -04001623 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001624 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001625 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001626
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001627 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001628}
1629
Geoff Langf6db0982015-08-25 13:04:00 -04001630Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1631{
1632 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001633 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001634 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001635
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001636 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001637}
1638
1639Error Context::drawElements(GLenum mode,
1640 GLsizei count,
1641 GLenum type,
1642 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001643 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001644{
Jamie Madill1b94d432015-08-07 13:23:23 -04001645 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001646 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001647}
1648
1649Error Context::drawElementsInstanced(GLenum mode,
1650 GLsizei count,
1651 GLenum type,
1652 const GLvoid *indices,
1653 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001654 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001655{
1656 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001657 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1658 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001659}
1660
1661Error Context::drawRangeElements(GLenum mode,
1662 GLuint start,
1663 GLuint end,
1664 GLsizei count,
1665 GLenum type,
1666 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001667 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001668{
1669 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001670 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001671}
1672
Geoff Lang129753a2015-01-09 16:52:09 -05001673Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001674{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001675 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001676}
1677
1678Error Context::finish()
1679{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001680 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001681}
1682
Austin Kinross6ee1e782015-05-29 17:05:37 -07001683void Context::insertEventMarker(GLsizei length, const char *marker)
1684{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001685 ASSERT(mImplementation);
1686 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001687}
1688
1689void Context::pushGroupMarker(GLsizei length, const char *marker)
1690{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001691 ASSERT(mImplementation);
1692 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001693}
1694
1695void Context::popGroupMarker()
1696{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001697 ASSERT(mImplementation);
1698 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001699}
1700
Geoff Langd8605522016-04-13 10:19:12 -04001701void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1702{
1703 Program *programObject = getProgram(program);
1704 ASSERT(programObject);
1705
1706 programObject->bindUniformLocation(location, name);
1707}
1708
Sami Väisänena797e062016-05-12 15:23:40 +03001709void Context::setCoverageModulation(GLenum components)
1710{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001711 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001712}
1713
Sami Väisänene45e53b2016-05-25 10:36:04 +03001714void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1715{
1716 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1717}
1718
1719void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1720{
1721 GLfloat I[16];
1722 angle::Matrix<GLfloat>::setToIdentity(I);
1723
1724 mGLState.loadPathRenderingMatrix(matrixMode, I);
1725}
1726
1727void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1728{
1729 const auto *pathObj = mResourceManager->getPath(path);
1730 if (!pathObj)
1731 return;
1732
1733 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1734 syncRendererState();
1735
1736 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1737}
1738
1739void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1740{
1741 const auto *pathObj = mResourceManager->getPath(path);
1742 if (!pathObj)
1743 return;
1744
1745 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1746 syncRendererState();
1747
1748 mImplementation->stencilStrokePath(pathObj, reference, mask);
1749}
1750
1751void Context::coverFillPath(GLuint path, GLenum coverMode)
1752{
1753 const auto *pathObj = mResourceManager->getPath(path);
1754 if (!pathObj)
1755 return;
1756
1757 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1758 syncRendererState();
1759
1760 mImplementation->coverFillPath(pathObj, coverMode);
1761}
1762
1763void Context::coverStrokePath(GLuint path, GLenum coverMode)
1764{
1765 const auto *pathObj = mResourceManager->getPath(path);
1766 if (!pathObj)
1767 return;
1768
1769 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1770 syncRendererState();
1771
1772 mImplementation->coverStrokePath(pathObj, coverMode);
1773}
1774
1775void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1776{
1777 const auto *pathObj = mResourceManager->getPath(path);
1778 if (!pathObj)
1779 return;
1780
1781 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1782 syncRendererState();
1783
1784 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1785}
1786
1787void Context::stencilThenCoverStrokePath(GLuint path,
1788 GLint reference,
1789 GLuint mask,
1790 GLenum coverMode)
1791{
1792 const auto *pathObj = mResourceManager->getPath(path);
1793 if (!pathObj)
1794 return;
1795
1796 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1797 syncRendererState();
1798
1799 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1800}
1801
Sami Väisänend59ca052016-06-21 16:10:00 +03001802void Context::coverFillPathInstanced(GLsizei numPaths,
1803 GLenum pathNameType,
1804 const void *paths,
1805 GLuint pathBase,
1806 GLenum coverMode,
1807 GLenum transformType,
1808 const GLfloat *transformValues)
1809{
1810 const auto &pathObjects =
1811 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1812
1813 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1814 syncRendererState();
1815
1816 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1817}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001818
Sami Väisänend59ca052016-06-21 16:10:00 +03001819void Context::coverStrokePathInstanced(GLsizei numPaths,
1820 GLenum pathNameType,
1821 const void *paths,
1822 GLuint pathBase,
1823 GLenum coverMode,
1824 GLenum transformType,
1825 const GLfloat *transformValues)
1826{
1827 const auto &pathObjects =
1828 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1829
1830 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1831 syncRendererState();
1832
1833 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1834 transformValues);
1835}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001836
Sami Väisänend59ca052016-06-21 16:10:00 +03001837void Context::stencilFillPathInstanced(GLsizei numPaths,
1838 GLenum pathNameType,
1839 const void *paths,
1840 GLuint pathBase,
1841 GLenum fillMode,
1842 GLuint mask,
1843 GLenum transformType,
1844 const GLfloat *transformValues)
1845{
1846 const auto &pathObjects =
1847 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1848
1849 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1850 syncRendererState();
1851
1852 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1853 transformValues);
1854}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001855
Sami Väisänend59ca052016-06-21 16:10:00 +03001856void Context::stencilStrokePathInstanced(GLsizei numPaths,
1857 GLenum pathNameType,
1858 const void *paths,
1859 GLuint pathBase,
1860 GLint reference,
1861 GLuint mask,
1862 GLenum transformType,
1863 const GLfloat *transformValues)
1864{
1865 const auto &pathObjects =
1866 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1867
1868 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1869 syncRendererState();
1870
1871 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1872 transformValues);
1873}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001874
Sami Väisänend59ca052016-06-21 16:10:00 +03001875void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1876 GLenum pathNameType,
1877 const void *paths,
1878 GLuint pathBase,
1879 GLenum fillMode,
1880 GLuint mask,
1881 GLenum coverMode,
1882 GLenum transformType,
1883 const GLfloat *transformValues)
1884{
1885 const auto &pathObjects =
1886 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1887
1888 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1889 syncRendererState();
1890
1891 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1892 transformType, transformValues);
1893}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001894
Sami Väisänend59ca052016-06-21 16:10:00 +03001895void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1896 GLenum pathNameType,
1897 const void *paths,
1898 GLuint pathBase,
1899 GLint reference,
1900 GLuint mask,
1901 GLenum coverMode,
1902 GLenum transformType,
1903 const GLfloat *transformValues)
1904{
1905 const auto &pathObjects =
1906 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1907
1908 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1909 syncRendererState();
1910
1911 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1912 transformType, transformValues);
1913}
1914
Sami Väisänen46eaa942016-06-29 10:26:37 +03001915void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1916{
1917 auto *programObject = getProgram(program);
1918
1919 programObject->bindFragmentInputLocation(location, name);
1920}
1921
1922void Context::programPathFragmentInputGen(GLuint program,
1923 GLint location,
1924 GLenum genMode,
1925 GLint components,
1926 const GLfloat *coeffs)
1927{
1928 auto *programObject = getProgram(program);
1929
1930 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1931}
1932
Jamie Madill437fa652016-05-03 15:13:24 -04001933void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001934{
Geoff Langda5777c2014-07-11 09:52:58 -04001935 if (error.isError())
1936 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001937 GLenum code = error.getCode();
1938 mErrors.insert(code);
1939 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1940 {
1941 markContextLost();
1942 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001943
1944 if (!error.getMessage().empty())
1945 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001946 auto *debug = &mGLState.getDebug();
1947 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1948 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001949 }
Geoff Langda5777c2014-07-11 09:52:58 -04001950 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001951}
1952
1953// Get one of the recorded errors and clear its flag, if any.
1954// [OpenGL ES 2.0.24] section 2.5 page 13.
1955GLenum Context::getError()
1956{
Geoff Langda5777c2014-07-11 09:52:58 -04001957 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001958 {
Geoff Langda5777c2014-07-11 09:52:58 -04001959 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001960 }
Geoff Langda5777c2014-07-11 09:52:58 -04001961 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001962 {
Geoff Langda5777c2014-07-11 09:52:58 -04001963 GLenum error = *mErrors.begin();
1964 mErrors.erase(mErrors.begin());
1965 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001966 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001967}
1968
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001969// NOTE: this function should not assume that this context is current!
1970void Context::markContextLost()
1971{
1972 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001973 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001974 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001975 mContextLostForced = true;
1976 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001977 mContextLost = true;
1978}
1979
1980bool Context::isContextLost()
1981{
1982 return mContextLost;
1983}
1984
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001985GLenum Context::getResetStatus()
1986{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001987 // Even if the application doesn't want to know about resets, we want to know
1988 // as it will allow us to skip all the calls.
1989 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001990 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001991 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001992 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001993 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001994 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001995
1996 // EXT_robustness, section 2.6: If the reset notification behavior is
1997 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1998 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1999 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002000 }
2001
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002002 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2003 // status should be returned at least once, and GL_NO_ERROR should be returned
2004 // once the device has finished resetting.
2005 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002006 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002007 ASSERT(mResetStatus == GL_NO_ERROR);
2008 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002009
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002010 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002011 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002012 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002013 }
2014 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002015 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002016 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002017 // If markContextLost was used to mark the context lost then
2018 // assume that is not recoverable, and continue to report the
2019 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002020 mResetStatus = mImplementation->getResetStatus();
2021 }
Jamie Madill893ab082014-05-16 16:56:10 -04002022
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002023 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002024}
2025
2026bool Context::isResetNotificationEnabled()
2027{
2028 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2029}
2030
Corentin Walleze3b10e82015-05-20 11:06:25 -04002031const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002032{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002033 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002034}
2035
2036EGLenum Context::getClientType() const
2037{
2038 return mClientType;
2039}
2040
2041EGLenum Context::getRenderBuffer() const
2042{
Corentin Wallez37c39792015-08-20 14:19:46 -04002043 auto framebufferIt = mFramebufferMap.find(0);
2044 if (framebufferIt != mFramebufferMap.end())
2045 {
2046 const Framebuffer *framebuffer = framebufferIt->second;
2047 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2048
2049 ASSERT(backAttachment != nullptr);
2050 return backAttachment->getSurface()->getRenderBuffer();
2051 }
2052 else
2053 {
2054 return EGL_NONE;
2055 }
Régis Fénéon83107972015-02-05 12:57:44 +01002056}
2057
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002058VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002059{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002060 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002061 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2062 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002063 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002064 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002066 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002067 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002068
2069 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002070}
2071
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002072TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002073{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002074 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002075 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2076 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002077 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002078 transformFeedback =
2079 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002080 transformFeedback->addRef();
2081 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002082 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002083
2084 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002085}
2086
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002087Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2088{
2089 // Can be called from Bind without a prior call to Gen.
2090 auto framebufferIt = mFramebufferMap.find(framebuffer);
2091 bool neverCreated = framebufferIt == mFramebufferMap.end();
2092 if (neverCreated || framebufferIt->second == nullptr)
2093 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002094 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002095 if (neverCreated)
2096 {
2097 mFramebufferHandleAllocator.reserve(framebuffer);
2098 mFramebufferMap[framebuffer] = newFBO;
2099 return newFBO;
2100 }
2101
2102 framebufferIt->second = newFBO;
2103 }
2104
2105 return framebufferIt->second;
2106}
2107
Geoff Lang36167ab2015-12-07 10:27:14 -05002108bool Context::isVertexArrayGenerated(GLuint vertexArray)
2109{
Geoff Langf41a7152016-09-19 15:11:17 -04002110 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002111 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2112}
2113
2114bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2115{
Geoff Langf41a7152016-09-19 15:11:17 -04002116 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002117 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2118}
2119
Shannon Woods53a94a82014-06-24 15:20:36 -04002120void Context::detachTexture(GLuint texture)
2121{
2122 // Simple pass-through to State's detachTexture method, as textures do not require
2123 // allocation map management either here or in the resource manager at detach time.
2124 // Zero textures are held by the Context, and we don't attempt to request them from
2125 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002126 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002127}
2128
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002129void Context::detachBuffer(GLuint buffer)
2130{
Yuly Novikov5807a532015-12-03 13:01:22 -05002131 // Simple pass-through to State's detachBuffer method, since
2132 // only buffer attachments to container objects that are bound to the current context
2133 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002134
Yuly Novikov5807a532015-12-03 13:01:22 -05002135 // [OpenGL ES 3.2] section 5.1.2 page 45:
2136 // Attachments to unbound container objects, such as
2137 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2138 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002139 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002140}
2141
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002142void Context::detachFramebuffer(GLuint framebuffer)
2143{
Shannon Woods53a94a82014-06-24 15:20:36 -04002144 // Framebuffer detachment is handled by Context, because 0 is a valid
2145 // Framebuffer object, and a pointer to it must be passed from Context
2146 // to State at binding time.
2147
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002148 // [OpenGL ES 2.0.24] section 4.4 page 107:
2149 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2150 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2151
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002152 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002153 {
2154 bindReadFramebuffer(0);
2155 }
2156
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002157 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002158 {
2159 bindDrawFramebuffer(0);
2160 }
2161}
2162
2163void Context::detachRenderbuffer(GLuint renderbuffer)
2164{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002165 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002166}
2167
Jamie Madill57a89722013-07-02 11:57:03 -04002168void Context::detachVertexArray(GLuint vertexArray)
2169{
Jamie Madill77a72f62015-04-14 11:18:32 -04002170 // Vertex array detachment is handled by Context, because 0 is a valid
2171 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002172 // binding time.
2173
Jamie Madill57a89722013-07-02 11:57:03 -04002174 // [OpenGL ES 3.0.2] section 2.10 page 43:
2175 // If a vertex array object that is currently bound is deleted, the binding
2176 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002177 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002178 {
2179 bindVertexArray(0);
2180 }
2181}
2182
Geoff Langc8058452014-02-03 12:04:11 -05002183void Context::detachTransformFeedback(GLuint transformFeedback)
2184{
Corentin Walleza2257da2016-04-19 16:43:12 -04002185 // Transform feedback detachment is handled by Context, because 0 is a valid
2186 // transform feedback, and a pointer to it must be passed from Context to State at
2187 // binding time.
2188
2189 // The OpenGL specification doesn't mention what should happen when the currently bound
2190 // transform feedback object is deleted. Since it is a container object, we treat it like
2191 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002192 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002193 {
2194 bindTransformFeedback(0);
2195 }
Geoff Langc8058452014-02-03 12:04:11 -05002196}
2197
Jamie Madilldc356042013-07-19 16:36:57 -04002198void Context::detachSampler(GLuint sampler)
2199{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002200 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002201}
2202
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002203void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2204{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002205 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002206}
2207
Jamie Madille29d1672013-07-19 16:36:57 -04002208void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2209{
Geoff Langc1984ed2016-10-07 12:41:00 -04002210 Sampler *samplerObject =
2211 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2212 SetSamplerParameteri(samplerObject, pname, param);
2213}
Jamie Madille29d1672013-07-19 16:36:57 -04002214
Geoff Langc1984ed2016-10-07 12:41:00 -04002215void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2216{
2217 Sampler *samplerObject =
2218 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2219 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002220}
2221
2222void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2223{
Geoff Langc1984ed2016-10-07 12:41:00 -04002224 Sampler *samplerObject =
2225 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2226 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002227}
2228
Geoff Langc1984ed2016-10-07 12:41:00 -04002229void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002230{
Geoff Langc1984ed2016-10-07 12:41:00 -04002231 Sampler *samplerObject =
2232 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2233 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002234}
2235
Geoff Langc1984ed2016-10-07 12:41:00 -04002236void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002237{
Geoff Langc1984ed2016-10-07 12:41:00 -04002238 const Sampler *samplerObject =
2239 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2240 QuerySamplerParameteriv(samplerObject, pname, params);
2241}
Jamie Madill9675b802013-07-19 16:36:59 -04002242
Geoff Langc1984ed2016-10-07 12:41:00 -04002243void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2244{
2245 const Sampler *samplerObject =
2246 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2247 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002248}
2249
Olli Etuahof0fee072016-03-30 15:11:58 +03002250void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2251{
2252 gl::Program *programObject = getProgram(program);
2253 ASSERT(programObject != nullptr);
2254
2255 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2256 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2257}
2258
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002259void Context::initRendererString()
2260{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002261 std::ostringstream rendererString;
2262 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002263 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002264 rendererString << ")";
2265
Geoff Langcec35902014-04-16 10:52:36 -04002266 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002267}
2268
Geoff Langc339c4e2016-11-29 10:37:36 -05002269void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002270{
Geoff Langc339c4e2016-11-29 10:37:36 -05002271 const Version &clientVersion = getClientVersion();
2272
2273 std::ostringstream versionString;
2274 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2275 << ANGLE_VERSION_STRING << ")";
2276 mVersionString = MakeStaticString(versionString.str());
2277
2278 std::ostringstream shadingLanguageVersionString;
2279 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2280 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2281 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2282 << ")";
2283 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002284}
2285
Geoff Langcec35902014-04-16 10:52:36 -04002286void Context::initExtensionStrings()
2287{
Geoff Langc339c4e2016-11-29 10:37:36 -05002288 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2289 std::ostringstream combinedStringStream;
2290 std::copy(strings.begin(), strings.end(),
2291 std::ostream_iterator<const char *>(combinedStringStream, " "));
2292 return MakeStaticString(combinedStringStream.str());
2293 };
2294
2295 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002296 for (const auto &extensionString : mExtensions.getStrings())
2297 {
2298 mExtensionStrings.push_back(MakeStaticString(extensionString));
2299 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002300 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002301
Geoff Langc339c4e2016-11-29 10:37:36 -05002302 mRequestableExtensionStrings.clear();
2303 for (const auto &extensionInfo : GetExtensionInfoMap())
2304 {
2305 if (extensionInfo.second.Requestable &&
2306 !(mExtensions.*(extensionInfo.second.ExtensionsMember)))
2307 {
2308 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2309 }
2310 }
2311 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002312}
2313
Geoff Langc339c4e2016-11-29 10:37:36 -05002314const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002315{
Geoff Langc339c4e2016-11-29 10:37:36 -05002316 switch (name)
2317 {
2318 case GL_VENDOR:
2319 return reinterpret_cast<const GLubyte *>("Google Inc.");
2320
2321 case GL_RENDERER:
2322 return reinterpret_cast<const GLubyte *>(mRendererString);
2323
2324 case GL_VERSION:
2325 return reinterpret_cast<const GLubyte *>(mVersionString);
2326
2327 case GL_SHADING_LANGUAGE_VERSION:
2328 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2329
2330 case GL_EXTENSIONS:
2331 return reinterpret_cast<const GLubyte *>(mExtensionString);
2332
2333 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2334 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2335
2336 default:
2337 UNREACHABLE();
2338 return nullptr;
2339 }
Geoff Langcec35902014-04-16 10:52:36 -04002340}
2341
Geoff Langc339c4e2016-11-29 10:37:36 -05002342const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002343{
Geoff Langc339c4e2016-11-29 10:37:36 -05002344 switch (name)
2345 {
2346 case GL_EXTENSIONS:
2347 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2348
2349 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2350 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2351
2352 default:
2353 UNREACHABLE();
2354 return nullptr;
2355 }
Geoff Langcec35902014-04-16 10:52:36 -04002356}
2357
2358size_t Context::getExtensionStringCount() const
2359{
2360 return mExtensionStrings.size();
2361}
2362
Geoff Langc339c4e2016-11-29 10:37:36 -05002363void Context::requestExtension(const char *name)
2364{
2365 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2366 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2367 const auto &extension = extensionInfos.at(name);
2368 ASSERT(extension.Requestable);
2369
2370 if (mExtensions.*(extension.ExtensionsMember))
2371 {
2372 // Extension already enabled
2373 return;
2374 }
2375
2376 mExtensions.*(extension.ExtensionsMember) = true;
2377 updateCaps();
2378 initExtensionStrings();
2379}
2380
2381size_t Context::getRequestableExtensionStringCount() const
2382{
2383 return mRequestableExtensionStrings.size();
2384}
2385
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002386void Context::beginTransformFeedback(GLenum primitiveMode)
2387{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002388 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002389 ASSERT(transformFeedback != nullptr);
2390 ASSERT(!transformFeedback->isPaused());
2391
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002392 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002393}
2394
2395bool Context::hasActiveTransformFeedback(GLuint program) const
2396{
2397 for (auto pair : mTransformFeedbackMap)
2398 {
2399 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2400 {
2401 return true;
2402 }
2403 }
2404 return false;
2405}
2406
Geoff Langc287ea62016-09-16 14:46:51 -04002407void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002408{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002409 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002410
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002411 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002412
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002413 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002414
Geoff Langeb66a6e2016-10-31 13:06:12 -04002415 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002416 {
2417 // Disable ES3+ extensions
2418 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002419 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002420 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002421 }
2422
Geoff Langeb66a6e2016-10-31 13:06:12 -04002423 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002424 {
2425 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2426 //mExtensions.sRGB = false;
2427 }
2428
Jamie Madill00ed7a12016-05-19 13:13:38 -04002429 // Some extensions are always available because they are implemented in the GL layer.
2430 mExtensions.bindUniformLocation = true;
2431 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002432 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002433 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002434
2435 // Enable the no error extension if the context was created with the flag.
2436 mExtensions.noError = mSkipValidation;
2437
Geoff Lang70d0f492015-12-10 17:45:46 -05002438 // Explicitly enable GL_KHR_debug
2439 mExtensions.debug = true;
2440 mExtensions.maxDebugMessageLength = 1024;
2441 mExtensions.maxDebugLoggedMessages = 1024;
2442 mExtensions.maxDebugGroupStackDepth = 1024;
2443 mExtensions.maxLabelLength = 1024;
2444
Geoff Langff5b2d52016-09-07 11:32:23 -04002445 // Explicitly enable GL_ANGLE_robust_client_memory
2446 mExtensions.robustClientMemory = true;
2447
Geoff Lang301d1612014-07-09 10:34:37 -04002448 // Apply implementation limits
2449 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002450 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2451 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2452
2453 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002454
Geoff Langc287ea62016-09-16 14:46:51 -04002455 // WebGL compatibility
2456 mExtensions.webglCompatibility = webGLContext;
2457 for (const auto &extensionInfo : GetExtensionInfoMap())
2458 {
2459 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002460 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002461 {
2462 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2463 }
2464 }
2465
2466 // Generate texture caps
2467 updateCaps();
2468}
2469
2470void Context::updateCaps()
2471{
Geoff Lang900013c2014-07-07 11:32:19 -04002472 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002473 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002474
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002475 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002476 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2477 {
2478 GLenum format = i->first;
2479 TextureCaps formatCaps = i->second;
2480
Geoff Lang5d601382014-07-22 15:14:06 -04002481 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002482
Geoff Lang0d8b7242015-09-09 14:56:53 -04002483 // Update the format caps based on the client version and extensions.
2484 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2485 // ES3.
2486 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002487 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002488 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002489 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002490 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002491 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002492
2493 // OpenGL ES does not support multisampling with integer formats
2494 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002495 {
Geoff Langd87878e2014-09-19 15:42:59 -04002496 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002497 }
Geoff Langd87878e2014-09-19 15:42:59 -04002498
2499 if (formatCaps.texturable && formatInfo.compressed)
2500 {
2501 mCaps.compressedTextureFormats.push_back(format);
2502 }
2503
2504 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002505 }
2506}
2507
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002508void Context::initWorkarounds()
2509{
2510 // Lose the context upon out of memory error if the application is
2511 // expecting to watch for those events.
2512 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2513}
2514
Jamie Madill1b94d432015-08-07 13:23:23 -04002515void Context::syncRendererState()
2516{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002517 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2518 mImplementation->syncState(mGLState, dirtyBits);
2519 mGLState.clearDirtyBits();
2520 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002521}
2522
Jamie Madillad9f24e2016-02-12 09:27:24 -05002523void Context::syncRendererState(const State::DirtyBits &bitMask,
2524 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002525{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002526 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2527 mImplementation->syncState(mGLState, dirtyBits);
2528 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002529
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002530 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002531}
Jamie Madillc29968b2016-01-20 11:17:23 -05002532
2533void Context::blitFramebuffer(GLint srcX0,
2534 GLint srcY0,
2535 GLint srcX1,
2536 GLint srcY1,
2537 GLint dstX0,
2538 GLint dstY0,
2539 GLint dstX1,
2540 GLint dstY1,
2541 GLbitfield mask,
2542 GLenum filter)
2543{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002544 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002545 ASSERT(drawFramebuffer);
2546
2547 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2548 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2549
Jamie Madillad9f24e2016-02-12 09:27:24 -05002550 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002551
Jamie Madill8415b5f2016-04-26 13:41:39 -04002552 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002553}
Jamie Madillc29968b2016-01-20 11:17:23 -05002554
2555void Context::clear(GLbitfield mask)
2556{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002557 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002558 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002559}
2560
2561void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2562{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002563 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002564 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2565 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002566}
2567
2568void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2569{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002570 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002571 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2572 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002573}
2574
2575void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2576{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002577 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002578 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2579 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002580}
2581
2582void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2583{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002584 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002585 ASSERT(framebufferObject);
2586
2587 // If a buffer is not present, the clear has no effect
2588 if (framebufferObject->getDepthbuffer() == nullptr &&
2589 framebufferObject->getStencilbuffer() == nullptr)
2590 {
2591 return;
2592 }
2593
Jamie Madillad9f24e2016-02-12 09:27:24 -05002594 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002595 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2596 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002597}
2598
2599void Context::readPixels(GLint x,
2600 GLint y,
2601 GLsizei width,
2602 GLsizei height,
2603 GLenum format,
2604 GLenum type,
2605 GLvoid *pixels)
2606{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002607 if (width == 0 || height == 0)
2608 {
2609 return;
2610 }
2611
Jamie Madillad9f24e2016-02-12 09:27:24 -05002612 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002613
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002614 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002615 ASSERT(framebufferObject);
2616
2617 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002618 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002619}
2620
2621void Context::copyTexImage2D(GLenum target,
2622 GLint level,
2623 GLenum internalformat,
2624 GLint x,
2625 GLint y,
2626 GLsizei width,
2627 GLsizei height,
2628 GLint border)
2629{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002630 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002631 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002632
Jamie Madillc29968b2016-01-20 11:17:23 -05002633 Rectangle sourceArea(x, y, width, height);
2634
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002635 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002636 Texture *texture =
2637 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002638 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002639}
2640
2641void Context::copyTexSubImage2D(GLenum target,
2642 GLint level,
2643 GLint xoffset,
2644 GLint yoffset,
2645 GLint x,
2646 GLint y,
2647 GLsizei width,
2648 GLsizei height)
2649{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002650 if (width == 0 || height == 0)
2651 {
2652 return;
2653 }
2654
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002655 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002656 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002657
Jamie Madillc29968b2016-01-20 11:17:23 -05002658 Offset destOffset(xoffset, yoffset, 0);
2659 Rectangle sourceArea(x, y, width, height);
2660
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002661 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002662 Texture *texture =
2663 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002664 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002665}
2666
2667void Context::copyTexSubImage3D(GLenum target,
2668 GLint level,
2669 GLint xoffset,
2670 GLint yoffset,
2671 GLint zoffset,
2672 GLint x,
2673 GLint y,
2674 GLsizei width,
2675 GLsizei height)
2676{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002677 if (width == 0 || height == 0)
2678 {
2679 return;
2680 }
2681
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002682 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002683 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002684
Jamie Madillc29968b2016-01-20 11:17:23 -05002685 Offset destOffset(xoffset, yoffset, zoffset);
2686 Rectangle sourceArea(x, y, width, height);
2687
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002688 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002689 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002690 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002691}
2692
2693void Context::framebufferTexture2D(GLenum target,
2694 GLenum attachment,
2695 GLenum textarget,
2696 GLuint texture,
2697 GLint level)
2698{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002699 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002700 ASSERT(framebuffer);
2701
2702 if (texture != 0)
2703 {
2704 Texture *textureObj = getTexture(texture);
2705
2706 ImageIndex index = ImageIndex::MakeInvalid();
2707
2708 if (textarget == GL_TEXTURE_2D)
2709 {
2710 index = ImageIndex::Make2D(level);
2711 }
2712 else
2713 {
2714 ASSERT(IsCubeMapTextureTarget(textarget));
2715 index = ImageIndex::MakeCube(textarget, level);
2716 }
2717
2718 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2719 }
2720 else
2721 {
2722 framebuffer->resetAttachment(attachment);
2723 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002724
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002725 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002726}
2727
2728void Context::framebufferRenderbuffer(GLenum target,
2729 GLenum attachment,
2730 GLenum renderbuffertarget,
2731 GLuint renderbuffer)
2732{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002733 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002734 ASSERT(framebuffer);
2735
2736 if (renderbuffer != 0)
2737 {
2738 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2739 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2740 renderbufferObject);
2741 }
2742 else
2743 {
2744 framebuffer->resetAttachment(attachment);
2745 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002746
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002747 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002748}
2749
2750void Context::framebufferTextureLayer(GLenum target,
2751 GLenum attachment,
2752 GLuint texture,
2753 GLint level,
2754 GLint layer)
2755{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002756 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002757 ASSERT(framebuffer);
2758
2759 if (texture != 0)
2760 {
2761 Texture *textureObject = getTexture(texture);
2762
2763 ImageIndex index = ImageIndex::MakeInvalid();
2764
2765 if (textureObject->getTarget() == GL_TEXTURE_3D)
2766 {
2767 index = ImageIndex::Make3D(level, layer);
2768 }
2769 else
2770 {
2771 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2772 index = ImageIndex::Make2DArray(level, layer);
2773 }
2774
2775 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2776 }
2777 else
2778 {
2779 framebuffer->resetAttachment(attachment);
2780 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002781
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002782 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002783}
2784
2785void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2786{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002787 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002788 ASSERT(framebuffer);
2789 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002790 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002791}
2792
2793void Context::readBuffer(GLenum mode)
2794{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002795 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002796 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002797 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002798}
2799
2800void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2801{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002802 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002803 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002804
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002805 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002806 ASSERT(framebuffer);
2807
2808 // The specification isn't clear what should be done when the framebuffer isn't complete.
2809 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002810 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002811}
2812
2813void Context::invalidateFramebuffer(GLenum target,
2814 GLsizei numAttachments,
2815 const GLenum *attachments)
2816{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002817 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002818 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002819
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002820 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002821 ASSERT(framebuffer);
2822
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002823 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002824 {
Jamie Madill437fa652016-05-03 15:13:24 -04002825 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002826 }
Jamie Madill437fa652016-05-03 15:13:24 -04002827
2828 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002829}
2830
2831void Context::invalidateSubFramebuffer(GLenum target,
2832 GLsizei numAttachments,
2833 const GLenum *attachments,
2834 GLint x,
2835 GLint y,
2836 GLsizei width,
2837 GLsizei height)
2838{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002839 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002840 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002841
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002842 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002843 ASSERT(framebuffer);
2844
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002845 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002846 {
Jamie Madill437fa652016-05-03 15:13:24 -04002847 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002848 }
Jamie Madill437fa652016-05-03 15:13:24 -04002849
2850 Rectangle area(x, y, width, height);
2851 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002852}
2853
Jamie Madill73a84962016-02-12 09:27:23 -05002854void Context::texImage2D(GLenum target,
2855 GLint level,
2856 GLint internalformat,
2857 GLsizei width,
2858 GLsizei height,
2859 GLint border,
2860 GLenum format,
2861 GLenum type,
2862 const GLvoid *pixels)
2863{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002864 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002865
2866 Extents size(width, height, 1);
2867 Texture *texture =
2868 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002869 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002870 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002871}
2872
2873void Context::texImage3D(GLenum target,
2874 GLint level,
2875 GLint internalformat,
2876 GLsizei width,
2877 GLsizei height,
2878 GLsizei depth,
2879 GLint border,
2880 GLenum format,
2881 GLenum type,
2882 const GLvoid *pixels)
2883{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002884 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002885
2886 Extents size(width, height, depth);
2887 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002888 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002889 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002890}
2891
2892void Context::texSubImage2D(GLenum target,
2893 GLint level,
2894 GLint xoffset,
2895 GLint yoffset,
2896 GLsizei width,
2897 GLsizei height,
2898 GLenum format,
2899 GLenum type,
2900 const GLvoid *pixels)
2901{
2902 // Zero sized uploads are valid but no-ops
2903 if (width == 0 || height == 0)
2904 {
2905 return;
2906 }
2907
Jamie Madillad9f24e2016-02-12 09:27:24 -05002908 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002909
2910 Box area(xoffset, yoffset, 0, width, height, 1);
2911 Texture *texture =
2912 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002913 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002914 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002915}
2916
2917void Context::texSubImage3D(GLenum target,
2918 GLint level,
2919 GLint xoffset,
2920 GLint yoffset,
2921 GLint zoffset,
2922 GLsizei width,
2923 GLsizei height,
2924 GLsizei depth,
2925 GLenum format,
2926 GLenum type,
2927 const GLvoid *pixels)
2928{
2929 // Zero sized uploads are valid but no-ops
2930 if (width == 0 || height == 0 || depth == 0)
2931 {
2932 return;
2933 }
2934
Jamie Madillad9f24e2016-02-12 09:27:24 -05002935 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002936
2937 Box area(xoffset, yoffset, zoffset, width, height, depth);
2938 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002939 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002940 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002941}
2942
2943void Context::compressedTexImage2D(GLenum target,
2944 GLint level,
2945 GLenum internalformat,
2946 GLsizei width,
2947 GLsizei height,
2948 GLint border,
2949 GLsizei imageSize,
2950 const GLvoid *data)
2951{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002952 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002953
2954 Extents size(width, height, 1);
2955 Texture *texture =
2956 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002957 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2958 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002959 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002960}
2961
2962void Context::compressedTexImage3D(GLenum target,
2963 GLint level,
2964 GLenum internalformat,
2965 GLsizei width,
2966 GLsizei height,
2967 GLsizei depth,
2968 GLint border,
2969 GLsizei imageSize,
2970 const GLvoid *data)
2971{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002972 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002973
2974 Extents size(width, height, depth);
2975 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002976 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2977 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002978 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002979}
2980
2981void Context::compressedTexSubImage2D(GLenum target,
2982 GLint level,
2983 GLint xoffset,
2984 GLint yoffset,
2985 GLsizei width,
2986 GLsizei height,
2987 GLenum format,
2988 GLsizei imageSize,
2989 const GLvoid *data)
2990{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002991 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002992
2993 Box area(xoffset, yoffset, 0, width, height, 1);
2994 Texture *texture =
2995 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002996 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2997 format, imageSize,
2998 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002999}
3000
3001void Context::compressedTexSubImage3D(GLenum target,
3002 GLint level,
3003 GLint xoffset,
3004 GLint yoffset,
3005 GLint zoffset,
3006 GLsizei width,
3007 GLsizei height,
3008 GLsizei depth,
3009 GLenum format,
3010 GLsizei imageSize,
3011 const GLvoid *data)
3012{
3013 // Zero sized uploads are valid but no-ops
3014 if (width == 0 || height == 0)
3015 {
3016 return;
3017 }
3018
Jamie Madillad9f24e2016-02-12 09:27:24 -05003019 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003020
3021 Box area(xoffset, yoffset, zoffset, width, height, depth);
3022 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003023 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3024 format, imageSize,
3025 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003026}
3027
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003028void Context::generateMipmap(GLenum target)
3029{
3030 Texture *texture = getTargetTexture(target);
3031 handleError(texture->generateMipmap());
3032}
3033
Geoff Lang97073d12016-04-20 10:42:34 -07003034void Context::copyTextureCHROMIUM(GLuint sourceId,
3035 GLuint destId,
3036 GLint internalFormat,
3037 GLenum destType,
3038 GLboolean unpackFlipY,
3039 GLboolean unpackPremultiplyAlpha,
3040 GLboolean unpackUnmultiplyAlpha)
3041{
3042 syncStateForTexImage();
3043
3044 gl::Texture *sourceTexture = getTexture(sourceId);
3045 gl::Texture *destTexture = getTexture(destId);
3046 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3047 unpackPremultiplyAlpha == GL_TRUE,
3048 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3049}
3050
3051void Context::copySubTextureCHROMIUM(GLuint sourceId,
3052 GLuint destId,
3053 GLint xoffset,
3054 GLint yoffset,
3055 GLint x,
3056 GLint y,
3057 GLsizei width,
3058 GLsizei height,
3059 GLboolean unpackFlipY,
3060 GLboolean unpackPremultiplyAlpha,
3061 GLboolean unpackUnmultiplyAlpha)
3062{
3063 // Zero sized copies are valid but no-ops
3064 if (width == 0 || height == 0)
3065 {
3066 return;
3067 }
3068
3069 syncStateForTexImage();
3070
3071 gl::Texture *sourceTexture = getTexture(sourceId);
3072 gl::Texture *destTexture = getTexture(destId);
3073 Offset offset(xoffset, yoffset, 0);
3074 Rectangle area(x, y, width, height);
3075 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3076 unpackPremultiplyAlpha == GL_TRUE,
3077 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3078}
3079
Geoff Lang47110bf2016-04-20 11:13:22 -07003080void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3081{
3082 syncStateForTexImage();
3083
3084 gl::Texture *sourceTexture = getTexture(sourceId);
3085 gl::Texture *destTexture = getTexture(destId);
3086 handleError(destTexture->copyCompressedTexture(sourceTexture));
3087}
3088
Geoff Lang496c02d2016-10-20 11:38:11 -07003089void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003090{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003091 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003092 ASSERT(buffer);
3093
Geoff Lang496c02d2016-10-20 11:38:11 -07003094 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003095}
3096
3097GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3098{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003099 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003100 ASSERT(buffer);
3101
3102 Error error = buffer->map(access);
3103 if (error.isError())
3104 {
Jamie Madill437fa652016-05-03 15:13:24 -04003105 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003106 return nullptr;
3107 }
3108
3109 return buffer->getMapPointer();
3110}
3111
3112GLboolean Context::unmapBuffer(GLenum target)
3113{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003114 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003115 ASSERT(buffer);
3116
3117 GLboolean result;
3118 Error error = buffer->unmap(&result);
3119 if (error.isError())
3120 {
Jamie Madill437fa652016-05-03 15:13:24 -04003121 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003122 return GL_FALSE;
3123 }
3124
3125 return result;
3126}
3127
3128GLvoid *Context::mapBufferRange(GLenum target,
3129 GLintptr offset,
3130 GLsizeiptr length,
3131 GLbitfield access)
3132{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003133 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003134 ASSERT(buffer);
3135
3136 Error error = buffer->mapRange(offset, length, access);
3137 if (error.isError())
3138 {
Jamie Madill437fa652016-05-03 15:13:24 -04003139 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003140 return nullptr;
3141 }
3142
3143 return buffer->getMapPointer();
3144}
3145
3146void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3147{
3148 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3149}
3150
Jamie Madillad9f24e2016-02-12 09:27:24 -05003151void Context::syncStateForReadPixels()
3152{
3153 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3154}
3155
3156void Context::syncStateForTexImage()
3157{
3158 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3159}
3160
3161void Context::syncStateForClear()
3162{
3163 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3164}
3165
3166void Context::syncStateForBlit()
3167{
3168 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3169}
3170
Jamie Madillc20ab272016-06-09 07:20:46 -07003171void Context::activeTexture(GLenum texture)
3172{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003173 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003174}
3175
3176void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3177{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003178 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003179}
3180
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003181void Context::blendEquation(GLenum mode)
3182{
3183 mGLState.setBlendEquation(mode, mode);
3184}
3185
Jamie Madillc20ab272016-06-09 07:20:46 -07003186void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3187{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003188 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003189}
3190
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003191void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3192{
3193 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3194}
3195
Jamie Madillc20ab272016-06-09 07:20:46 -07003196void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3197{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003198 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003199}
3200
3201void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3202{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003203 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003204}
3205
3206void Context::clearDepthf(GLclampf depth)
3207{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003208 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003209}
3210
3211void Context::clearStencil(GLint s)
3212{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003213 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003214}
3215
3216void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3217{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003218 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003219}
3220
3221void Context::cullFace(GLenum mode)
3222{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003223 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003224}
3225
3226void Context::depthFunc(GLenum func)
3227{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003228 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003229}
3230
3231void Context::depthMask(GLboolean flag)
3232{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003233 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003234}
3235
3236void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3237{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003238 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003239}
3240
3241void Context::disable(GLenum cap)
3242{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003243 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003244}
3245
3246void Context::disableVertexAttribArray(GLuint index)
3247{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003248 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003249}
3250
3251void Context::enable(GLenum cap)
3252{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003253 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003254}
3255
3256void Context::enableVertexAttribArray(GLuint index)
3257{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003258 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003259}
3260
3261void Context::frontFace(GLenum mode)
3262{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003263 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003264}
3265
3266void Context::hint(GLenum target, GLenum mode)
3267{
3268 switch (target)
3269 {
3270 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003271 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003272 break;
3273
3274 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003275 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003276 break;
3277
3278 default:
3279 UNREACHABLE();
3280 return;
3281 }
3282}
3283
3284void Context::lineWidth(GLfloat width)
3285{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003286 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003287}
3288
3289void Context::pixelStorei(GLenum pname, GLint param)
3290{
3291 switch (pname)
3292 {
3293 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003294 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003295 break;
3296
3297 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003298 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003299 break;
3300
3301 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003302 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003303 break;
3304
3305 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003306 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003307 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003308 break;
3309
3310 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003311 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003312 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003313 break;
3314
3315 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003316 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003317 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003318 break;
3319
3320 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003321 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003322 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003323 break;
3324
3325 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003326 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003327 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003328 break;
3329
3330 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003331 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003332 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003333 break;
3334
3335 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003336 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003337 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003338 break;
3339
3340 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003341 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003342 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003343 break;
3344
3345 default:
3346 UNREACHABLE();
3347 return;
3348 }
3349}
3350
3351void Context::polygonOffset(GLfloat factor, GLfloat units)
3352{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003353 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003354}
3355
3356void Context::sampleCoverage(GLclampf value, GLboolean invert)
3357{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003358 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003359}
3360
3361void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3362{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003363 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003364}
3365
3366void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3367{
3368 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3369 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003370 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003371 }
3372
3373 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3374 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003375 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003376 }
3377}
3378
3379void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3380{
3381 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3382 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003383 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003384 }
3385
3386 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3387 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003388 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003389 }
3390}
3391
3392void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3393{
3394 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3395 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003396 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003397 }
3398
3399 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3400 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003401 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003402 }
3403}
3404
3405void Context::vertexAttrib1f(GLuint index, GLfloat x)
3406{
3407 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003408 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003409}
3410
3411void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3412{
3413 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003414 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003415}
3416
3417void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3418{
3419 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003420 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003421}
3422
3423void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3424{
3425 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003426 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003427}
3428
3429void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3430{
3431 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003432 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003433}
3434
3435void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3436{
3437 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003438 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003439}
3440
3441void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3442{
3443 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003444 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003445}
3446
3447void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3448{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003449 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003450}
3451
3452void Context::vertexAttribPointer(GLuint index,
3453 GLint size,
3454 GLenum type,
3455 GLboolean normalized,
3456 GLsizei stride,
3457 const GLvoid *ptr)
3458{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3460 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003461}
3462
3463void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3464{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003466}
3467
3468void Context::vertexAttribIPointer(GLuint index,
3469 GLint size,
3470 GLenum type,
3471 GLsizei stride,
3472 const GLvoid *pointer)
3473{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003474 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3475 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003476}
3477
3478void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3479{
3480 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003481 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003482}
3483
3484void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3485{
3486 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003487 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003488}
3489
3490void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3491{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003492 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003493}
3494
3495void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3496{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003497 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003498}
3499
3500void Context::debugMessageControl(GLenum source,
3501 GLenum type,
3502 GLenum severity,
3503 GLsizei count,
3504 const GLuint *ids,
3505 GLboolean enabled)
3506{
3507 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3509 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003510}
3511
3512void Context::debugMessageInsert(GLenum source,
3513 GLenum type,
3514 GLuint id,
3515 GLenum severity,
3516 GLsizei length,
3517 const GLchar *buf)
3518{
3519 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
3523void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3524{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
3528GLuint Context::getDebugMessageLog(GLuint count,
3529 GLsizei bufSize,
3530 GLenum *sources,
3531 GLenum *types,
3532 GLuint *ids,
3533 GLenum *severities,
3534 GLsizei *lengths,
3535 GLchar *messageLog)
3536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3538 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003539}
3540
3541void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3542{
3543 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003545}
3546
3547void Context::popDebugGroup()
3548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003550}
3551
Jamie Madill29639852016-09-02 15:00:09 -04003552void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3553{
3554 Buffer *buffer = mGLState.getTargetBuffer(target);
3555 ASSERT(buffer);
3556 handleError(buffer->bufferData(target, data, size, usage));
3557}
3558
3559void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3560{
3561 if (data == nullptr)
3562 {
3563 return;
3564 }
3565
3566 Buffer *buffer = mGLState.getTargetBuffer(target);
3567 ASSERT(buffer);
3568 handleError(buffer->bufferSubData(target, data, size, offset));
3569}
3570
Jamie Madillef300b12016-10-07 15:12:09 -04003571void Context::attachShader(GLuint program, GLuint shader)
3572{
3573 auto programObject = mResourceManager->getProgram(program);
3574 auto shaderObject = mResourceManager->getShader(shader);
3575 ASSERT(programObject && shaderObject);
3576 programObject->attachShader(shaderObject);
3577}
3578
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003579const Workarounds &Context::getWorkarounds() const
3580{
3581 return mWorkarounds;
3582}
3583
Jamie Madillb0817d12016-11-01 15:48:31 -04003584void Context::copyBufferSubData(GLenum readTarget,
3585 GLenum writeTarget,
3586 GLintptr readOffset,
3587 GLintptr writeOffset,
3588 GLsizeiptr size)
3589{
3590 // if size is zero, the copy is a successful no-op
3591 if (size == 0)
3592 {
3593 return;
3594 }
3595
3596 // TODO(jmadill): cache these.
3597 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3598 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3599
3600 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3601}
3602
Jamie Madill01a80ee2016-11-07 12:06:18 -05003603void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3604{
3605 Program *programObject = getProgram(program);
3606 // TODO(jmadill): Re-use this from the validation if possible.
3607 ASSERT(programObject);
3608 programObject->bindAttributeLocation(index, name);
3609}
3610
3611void Context::bindBuffer(GLenum target, GLuint buffer)
3612{
3613 switch (target)
3614 {
3615 case GL_ARRAY_BUFFER:
3616 bindArrayBuffer(buffer);
3617 break;
3618 case GL_ELEMENT_ARRAY_BUFFER:
3619 bindElementArrayBuffer(buffer);
3620 break;
3621 case GL_COPY_READ_BUFFER:
3622 bindCopyReadBuffer(buffer);
3623 break;
3624 case GL_COPY_WRITE_BUFFER:
3625 bindCopyWriteBuffer(buffer);
3626 break;
3627 case GL_PIXEL_PACK_BUFFER:
3628 bindPixelPackBuffer(buffer);
3629 break;
3630 case GL_PIXEL_UNPACK_BUFFER:
3631 bindPixelUnpackBuffer(buffer);
3632 break;
3633 case GL_UNIFORM_BUFFER:
3634 bindGenericUniformBuffer(buffer);
3635 break;
3636 case GL_TRANSFORM_FEEDBACK_BUFFER:
3637 bindGenericTransformFeedbackBuffer(buffer);
3638 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003639 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003640 if (buffer != 0)
3641 {
3642 // Binding buffers to this binding point is not implemented yet.
3643 UNIMPLEMENTED();
3644 }
Geoff Lang3b573612016-10-31 14:08:10 -04003645 break;
3646 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003647 if (buffer != 0)
3648 {
3649 // Binding buffers to this binding point is not implemented yet.
3650 UNIMPLEMENTED();
3651 }
Geoff Lang3b573612016-10-31 14:08:10 -04003652 break;
3653 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003654 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003655 break;
3656 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003657 if (buffer != 0)
3658 {
3659 // Binding buffers to this binding point is not implemented yet.
3660 UNIMPLEMENTED();
3661 }
Geoff Lang3b573612016-10-31 14:08:10 -04003662 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003663
3664 default:
3665 UNREACHABLE();
3666 break;
3667 }
3668}
3669
3670void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3671{
3672 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3673 {
3674 bindReadFramebuffer(framebuffer);
3675 }
3676
3677 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3678 {
3679 bindDrawFramebuffer(framebuffer);
3680 }
3681}
3682
3683void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3684{
3685 ASSERT(target == GL_RENDERBUFFER);
3686 Renderbuffer *object =
3687 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
3688 mGLState.setRenderbufferBinding(object);
3689}
3690
Jamie Madillc29968b2016-01-20 11:17:23 -05003691} // namespace gl