blob: cd248fb283498a2033e557fe003c37e1b86e8ac9 [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
Jamie Madill675fe712016-12-19 13:07:54 -05001621void 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 Madill675fe712016-12-19 13:07:54 -05001624 auto error = mImplementation->drawArrays(mode, first, count);
1625 handleError(error);
1626 if (!error.isError())
1627 {
1628 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1629 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001630}
1631
Jamie Madill675fe712016-12-19 13:07:54 -05001632void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001633{
1634 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001635 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1636 handleError(error);
1637 if (!error.isError())
1638 {
1639 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1640 }
Geoff Langf6db0982015-08-25 13:04:00 -04001641}
1642
Jamie Madill675fe712016-12-19 13:07:54 -05001643void Context::drawElements(GLenum mode,
1644 GLsizei count,
1645 GLenum type,
1646 const GLvoid *indices,
1647 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001648{
Jamie Madill1b94d432015-08-07 13:23:23 -04001649 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001650 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001651}
1652
Jamie Madill675fe712016-12-19 13:07:54 -05001653void Context::drawElementsInstanced(GLenum mode,
1654 GLsizei count,
1655 GLenum type,
1656 const GLvoid *indices,
1657 GLsizei instances,
1658 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001659{
1660 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001661 handleError(
1662 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001663}
1664
Jamie Madill675fe712016-12-19 13:07:54 -05001665void Context::drawRangeElements(GLenum mode,
1666 GLuint start,
1667 GLuint end,
1668 GLsizei count,
1669 GLenum type,
1670 const GLvoid *indices,
1671 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001672{
1673 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001674 handleError(
1675 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001676}
1677
Jiajia Qind9671222016-11-29 16:30:31 +08001678void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1679{
1680 syncRendererState();
1681 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1682}
1683
1684void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1685{
1686 syncRendererState();
1687 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1688}
1689
Jamie Madill675fe712016-12-19 13:07:54 -05001690void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001691{
Jamie Madill675fe712016-12-19 13:07:54 -05001692 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001693}
1694
Jamie Madill675fe712016-12-19 13:07:54 -05001695void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001696{
Jamie Madill675fe712016-12-19 13:07:54 -05001697 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001698}
1699
Austin Kinross6ee1e782015-05-29 17:05:37 -07001700void Context::insertEventMarker(GLsizei length, const char *marker)
1701{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001702 ASSERT(mImplementation);
1703 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001704}
1705
1706void Context::pushGroupMarker(GLsizei length, const char *marker)
1707{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001708 ASSERT(mImplementation);
1709 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001710}
1711
1712void Context::popGroupMarker()
1713{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001714 ASSERT(mImplementation);
1715 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001716}
1717
Geoff Langd8605522016-04-13 10:19:12 -04001718void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1719{
1720 Program *programObject = getProgram(program);
1721 ASSERT(programObject);
1722
1723 programObject->bindUniformLocation(location, name);
1724}
1725
Sami Väisänena797e062016-05-12 15:23:40 +03001726void Context::setCoverageModulation(GLenum components)
1727{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001728 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001729}
1730
Sami Väisänene45e53b2016-05-25 10:36:04 +03001731void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1732{
1733 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1734}
1735
1736void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1737{
1738 GLfloat I[16];
1739 angle::Matrix<GLfloat>::setToIdentity(I);
1740
1741 mGLState.loadPathRenderingMatrix(matrixMode, I);
1742}
1743
1744void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1745{
1746 const auto *pathObj = mResourceManager->getPath(path);
1747 if (!pathObj)
1748 return;
1749
1750 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1751 syncRendererState();
1752
1753 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1754}
1755
1756void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1757{
1758 const auto *pathObj = mResourceManager->getPath(path);
1759 if (!pathObj)
1760 return;
1761
1762 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1763 syncRendererState();
1764
1765 mImplementation->stencilStrokePath(pathObj, reference, mask);
1766}
1767
1768void Context::coverFillPath(GLuint path, GLenum coverMode)
1769{
1770 const auto *pathObj = mResourceManager->getPath(path);
1771 if (!pathObj)
1772 return;
1773
1774 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1775 syncRendererState();
1776
1777 mImplementation->coverFillPath(pathObj, coverMode);
1778}
1779
1780void Context::coverStrokePath(GLuint path, GLenum coverMode)
1781{
1782 const auto *pathObj = mResourceManager->getPath(path);
1783 if (!pathObj)
1784 return;
1785
1786 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1787 syncRendererState();
1788
1789 mImplementation->coverStrokePath(pathObj, coverMode);
1790}
1791
1792void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1793{
1794 const auto *pathObj = mResourceManager->getPath(path);
1795 if (!pathObj)
1796 return;
1797
1798 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1799 syncRendererState();
1800
1801 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1802}
1803
1804void Context::stencilThenCoverStrokePath(GLuint path,
1805 GLint reference,
1806 GLuint mask,
1807 GLenum coverMode)
1808{
1809 const auto *pathObj = mResourceManager->getPath(path);
1810 if (!pathObj)
1811 return;
1812
1813 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1814 syncRendererState();
1815
1816 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1817}
1818
Sami Väisänend59ca052016-06-21 16:10:00 +03001819void Context::coverFillPathInstanced(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->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1834}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001835
Sami Väisänend59ca052016-06-21 16:10:00 +03001836void Context::coverStrokePathInstanced(GLsizei numPaths,
1837 GLenum pathNameType,
1838 const void *paths,
1839 GLuint pathBase,
1840 GLenum coverMode,
1841 GLenum transformType,
1842 const GLfloat *transformValues)
1843{
1844 const auto &pathObjects =
1845 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1846
1847 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1848 syncRendererState();
1849
1850 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1851 transformValues);
1852}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001853
Sami Väisänend59ca052016-06-21 16:10:00 +03001854void Context::stencilFillPathInstanced(GLsizei numPaths,
1855 GLenum pathNameType,
1856 const void *paths,
1857 GLuint pathBase,
1858 GLenum fillMode,
1859 GLuint mask,
1860 GLenum transformType,
1861 const GLfloat *transformValues)
1862{
1863 const auto &pathObjects =
1864 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1865
1866 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1867 syncRendererState();
1868
1869 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1870 transformValues);
1871}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001872
Sami Väisänend59ca052016-06-21 16:10:00 +03001873void Context::stencilStrokePathInstanced(GLsizei numPaths,
1874 GLenum pathNameType,
1875 const void *paths,
1876 GLuint pathBase,
1877 GLint reference,
1878 GLuint mask,
1879 GLenum transformType,
1880 const GLfloat *transformValues)
1881{
1882 const auto &pathObjects =
1883 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1884
1885 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1886 syncRendererState();
1887
1888 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1889 transformValues);
1890}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001891
Sami Väisänend59ca052016-06-21 16:10:00 +03001892void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1893 GLenum pathNameType,
1894 const void *paths,
1895 GLuint pathBase,
1896 GLenum fillMode,
1897 GLuint mask,
1898 GLenum coverMode,
1899 GLenum transformType,
1900 const GLfloat *transformValues)
1901{
1902 const auto &pathObjects =
1903 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1904
1905 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1906 syncRendererState();
1907
1908 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1909 transformType, transformValues);
1910}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001911
Sami Väisänend59ca052016-06-21 16:10:00 +03001912void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1913 GLenum pathNameType,
1914 const void *paths,
1915 GLuint pathBase,
1916 GLint reference,
1917 GLuint mask,
1918 GLenum coverMode,
1919 GLenum transformType,
1920 const GLfloat *transformValues)
1921{
1922 const auto &pathObjects =
1923 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1924
1925 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1926 syncRendererState();
1927
1928 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1929 transformType, transformValues);
1930}
1931
Sami Väisänen46eaa942016-06-29 10:26:37 +03001932void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1933{
1934 auto *programObject = getProgram(program);
1935
1936 programObject->bindFragmentInputLocation(location, name);
1937}
1938
1939void Context::programPathFragmentInputGen(GLuint program,
1940 GLint location,
1941 GLenum genMode,
1942 GLint components,
1943 const GLfloat *coeffs)
1944{
1945 auto *programObject = getProgram(program);
1946
1947 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1948}
1949
Jamie Madill437fa652016-05-03 15:13:24 -04001950void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001951{
Geoff Langda5777c2014-07-11 09:52:58 -04001952 if (error.isError())
1953 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001954 GLenum code = error.getCode();
1955 mErrors.insert(code);
1956 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1957 {
1958 markContextLost();
1959 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001960
1961 if (!error.getMessage().empty())
1962 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001963 auto *debug = &mGLState.getDebug();
1964 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1965 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001966 }
Geoff Langda5777c2014-07-11 09:52:58 -04001967 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001968}
1969
1970// Get one of the recorded errors and clear its flag, if any.
1971// [OpenGL ES 2.0.24] section 2.5 page 13.
1972GLenum Context::getError()
1973{
Geoff Langda5777c2014-07-11 09:52:58 -04001974 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001975 {
Geoff Langda5777c2014-07-11 09:52:58 -04001976 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001977 }
Geoff Langda5777c2014-07-11 09:52:58 -04001978 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001979 {
Geoff Langda5777c2014-07-11 09:52:58 -04001980 GLenum error = *mErrors.begin();
1981 mErrors.erase(mErrors.begin());
1982 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001983 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001984}
1985
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001986// NOTE: this function should not assume that this context is current!
1987void Context::markContextLost()
1988{
1989 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001990 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001991 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001992 mContextLostForced = true;
1993 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001994 mContextLost = true;
1995}
1996
1997bool Context::isContextLost()
1998{
1999 return mContextLost;
2000}
2001
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002002GLenum Context::getResetStatus()
2003{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002004 // Even if the application doesn't want to know about resets, we want to know
2005 // as it will allow us to skip all the calls.
2006 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002007 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002008 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002009 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002010 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002011 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002012
2013 // EXT_robustness, section 2.6: If the reset notification behavior is
2014 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2015 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2016 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002017 }
2018
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002019 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2020 // status should be returned at least once, and GL_NO_ERROR should be returned
2021 // once the device has finished resetting.
2022 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002023 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002024 ASSERT(mResetStatus == GL_NO_ERROR);
2025 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002026
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002027 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002028 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002029 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002030 }
2031 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002032 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002033 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002034 // If markContextLost was used to mark the context lost then
2035 // assume that is not recoverable, and continue to report the
2036 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002037 mResetStatus = mImplementation->getResetStatus();
2038 }
Jamie Madill893ab082014-05-16 16:56:10 -04002039
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002040 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002041}
2042
2043bool Context::isResetNotificationEnabled()
2044{
2045 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2046}
2047
Corentin Walleze3b10e82015-05-20 11:06:25 -04002048const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002049{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002050 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002051}
2052
2053EGLenum Context::getClientType() const
2054{
2055 return mClientType;
2056}
2057
2058EGLenum Context::getRenderBuffer() const
2059{
Corentin Wallez37c39792015-08-20 14:19:46 -04002060 auto framebufferIt = mFramebufferMap.find(0);
2061 if (framebufferIt != mFramebufferMap.end())
2062 {
2063 const Framebuffer *framebuffer = framebufferIt->second;
2064 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2065
2066 ASSERT(backAttachment != nullptr);
2067 return backAttachment->getSurface()->getRenderBuffer();
2068 }
2069 else
2070 {
2071 return EGL_NONE;
2072 }
Régis Fénéon83107972015-02-05 12:57:44 +01002073}
2074
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002075VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002076{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002077 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002078 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2079 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002080 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002081 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2082
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002083 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002084 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002085
2086 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002087}
2088
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002089TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002090{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002091 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002092 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2093 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002094 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002095 transformFeedback =
2096 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002097 transformFeedback->addRef();
2098 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002099 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002100
2101 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002102}
2103
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002104Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2105{
2106 // Can be called from Bind without a prior call to Gen.
2107 auto framebufferIt = mFramebufferMap.find(framebuffer);
2108 bool neverCreated = framebufferIt == mFramebufferMap.end();
2109 if (neverCreated || framebufferIt->second == nullptr)
2110 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002111 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002112 if (neverCreated)
2113 {
2114 mFramebufferHandleAllocator.reserve(framebuffer);
2115 mFramebufferMap[framebuffer] = newFBO;
2116 return newFBO;
2117 }
2118
2119 framebufferIt->second = newFBO;
2120 }
2121
2122 return framebufferIt->second;
2123}
2124
Geoff Lang36167ab2015-12-07 10:27:14 -05002125bool Context::isVertexArrayGenerated(GLuint vertexArray)
2126{
Geoff Langf41a7152016-09-19 15:11:17 -04002127 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002128 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2129}
2130
2131bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2132{
Geoff Langf41a7152016-09-19 15:11:17 -04002133 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002134 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2135}
2136
Shannon Woods53a94a82014-06-24 15:20:36 -04002137void Context::detachTexture(GLuint texture)
2138{
2139 // Simple pass-through to State's detachTexture method, as textures do not require
2140 // allocation map management either here or in the resource manager at detach time.
2141 // Zero textures are held by the Context, and we don't attempt to request them from
2142 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002143 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002144}
2145
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002146void Context::detachBuffer(GLuint buffer)
2147{
Yuly Novikov5807a532015-12-03 13:01:22 -05002148 // Simple pass-through to State's detachBuffer method, since
2149 // only buffer attachments to container objects that are bound to the current context
2150 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002151
Yuly Novikov5807a532015-12-03 13:01:22 -05002152 // [OpenGL ES 3.2] section 5.1.2 page 45:
2153 // Attachments to unbound container objects, such as
2154 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2155 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002156 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002157}
2158
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002159void Context::detachFramebuffer(GLuint framebuffer)
2160{
Shannon Woods53a94a82014-06-24 15:20:36 -04002161 // Framebuffer detachment is handled by Context, because 0 is a valid
2162 // Framebuffer object, and a pointer to it must be passed from Context
2163 // to State at binding time.
2164
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002165 // [OpenGL ES 2.0.24] section 4.4 page 107:
2166 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2167 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2168
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002169 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002170 {
2171 bindReadFramebuffer(0);
2172 }
2173
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002174 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002175 {
2176 bindDrawFramebuffer(0);
2177 }
2178}
2179
2180void Context::detachRenderbuffer(GLuint renderbuffer)
2181{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002182 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002183}
2184
Jamie Madill57a89722013-07-02 11:57:03 -04002185void Context::detachVertexArray(GLuint vertexArray)
2186{
Jamie Madill77a72f62015-04-14 11:18:32 -04002187 // Vertex array detachment is handled by Context, because 0 is a valid
2188 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002189 // binding time.
2190
Jamie Madill57a89722013-07-02 11:57:03 -04002191 // [OpenGL ES 3.0.2] section 2.10 page 43:
2192 // If a vertex array object that is currently bound is deleted, the binding
2193 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002194 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002195 {
2196 bindVertexArray(0);
2197 }
2198}
2199
Geoff Langc8058452014-02-03 12:04:11 -05002200void Context::detachTransformFeedback(GLuint transformFeedback)
2201{
Corentin Walleza2257da2016-04-19 16:43:12 -04002202 // Transform feedback detachment is handled by Context, because 0 is a valid
2203 // transform feedback, and a pointer to it must be passed from Context to State at
2204 // binding time.
2205
2206 // The OpenGL specification doesn't mention what should happen when the currently bound
2207 // transform feedback object is deleted. Since it is a container object, we treat it like
2208 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002209 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002210 {
2211 bindTransformFeedback(0);
2212 }
Geoff Langc8058452014-02-03 12:04:11 -05002213}
2214
Jamie Madilldc356042013-07-19 16:36:57 -04002215void Context::detachSampler(GLuint sampler)
2216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002217 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002218}
2219
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002220void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2221{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002222 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002223}
2224
Jamie Madille29d1672013-07-19 16:36:57 -04002225void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2226{
Geoff Langc1984ed2016-10-07 12:41:00 -04002227 Sampler *samplerObject =
2228 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2229 SetSamplerParameteri(samplerObject, pname, param);
2230}
Jamie Madille29d1672013-07-19 16:36:57 -04002231
Geoff Langc1984ed2016-10-07 12:41:00 -04002232void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2233{
2234 Sampler *samplerObject =
2235 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2236 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002237}
2238
2239void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2240{
Geoff Langc1984ed2016-10-07 12:41:00 -04002241 Sampler *samplerObject =
2242 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2243 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002244}
2245
Geoff Langc1984ed2016-10-07 12:41:00 -04002246void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002247{
Geoff Langc1984ed2016-10-07 12:41:00 -04002248 Sampler *samplerObject =
2249 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2250 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002251}
2252
Geoff Langc1984ed2016-10-07 12:41:00 -04002253void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002254{
Geoff Langc1984ed2016-10-07 12:41:00 -04002255 const Sampler *samplerObject =
2256 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2257 QuerySamplerParameteriv(samplerObject, pname, params);
2258}
Jamie Madill9675b802013-07-19 16:36:59 -04002259
Geoff Langc1984ed2016-10-07 12:41:00 -04002260void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2261{
2262 const Sampler *samplerObject =
2263 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2264 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002265}
2266
Olli Etuahof0fee072016-03-30 15:11:58 +03002267void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2268{
2269 gl::Program *programObject = getProgram(program);
2270 ASSERT(programObject != nullptr);
2271
2272 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2273 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2274}
2275
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002276void Context::initRendererString()
2277{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002278 std::ostringstream rendererString;
2279 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002280 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002281 rendererString << ")";
2282
Geoff Langcec35902014-04-16 10:52:36 -04002283 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002284}
2285
Geoff Langc339c4e2016-11-29 10:37:36 -05002286void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002287{
Geoff Langc339c4e2016-11-29 10:37:36 -05002288 const Version &clientVersion = getClientVersion();
2289
2290 std::ostringstream versionString;
2291 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2292 << ANGLE_VERSION_STRING << ")";
2293 mVersionString = MakeStaticString(versionString.str());
2294
2295 std::ostringstream shadingLanguageVersionString;
2296 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2297 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2298 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2299 << ")";
2300 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002301}
2302
Geoff Langcec35902014-04-16 10:52:36 -04002303void Context::initExtensionStrings()
2304{
Geoff Langc339c4e2016-11-29 10:37:36 -05002305 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2306 std::ostringstream combinedStringStream;
2307 std::copy(strings.begin(), strings.end(),
2308 std::ostream_iterator<const char *>(combinedStringStream, " "));
2309 return MakeStaticString(combinedStringStream.str());
2310 };
2311
2312 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002313 for (const auto &extensionString : mExtensions.getStrings())
2314 {
2315 mExtensionStrings.push_back(MakeStaticString(extensionString));
2316 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002317 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002318
Geoff Langc339c4e2016-11-29 10:37:36 -05002319 mRequestableExtensionStrings.clear();
2320 for (const auto &extensionInfo : GetExtensionInfoMap())
2321 {
2322 if (extensionInfo.second.Requestable &&
2323 !(mExtensions.*(extensionInfo.second.ExtensionsMember)))
2324 {
2325 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2326 }
2327 }
2328 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002329}
2330
Geoff Langc339c4e2016-11-29 10:37:36 -05002331const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002332{
Geoff Langc339c4e2016-11-29 10:37:36 -05002333 switch (name)
2334 {
2335 case GL_VENDOR:
2336 return reinterpret_cast<const GLubyte *>("Google Inc.");
2337
2338 case GL_RENDERER:
2339 return reinterpret_cast<const GLubyte *>(mRendererString);
2340
2341 case GL_VERSION:
2342 return reinterpret_cast<const GLubyte *>(mVersionString);
2343
2344 case GL_SHADING_LANGUAGE_VERSION:
2345 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2346
2347 case GL_EXTENSIONS:
2348 return reinterpret_cast<const GLubyte *>(mExtensionString);
2349
2350 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2351 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2352
2353 default:
2354 UNREACHABLE();
2355 return nullptr;
2356 }
Geoff Langcec35902014-04-16 10:52:36 -04002357}
2358
Geoff Langc339c4e2016-11-29 10:37:36 -05002359const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002360{
Geoff Langc339c4e2016-11-29 10:37:36 -05002361 switch (name)
2362 {
2363 case GL_EXTENSIONS:
2364 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2365
2366 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2367 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2368
2369 default:
2370 UNREACHABLE();
2371 return nullptr;
2372 }
Geoff Langcec35902014-04-16 10:52:36 -04002373}
2374
2375size_t Context::getExtensionStringCount() const
2376{
2377 return mExtensionStrings.size();
2378}
2379
Geoff Langc339c4e2016-11-29 10:37:36 -05002380void Context::requestExtension(const char *name)
2381{
2382 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2383 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2384 const auto &extension = extensionInfos.at(name);
2385 ASSERT(extension.Requestable);
2386
2387 if (mExtensions.*(extension.ExtensionsMember))
2388 {
2389 // Extension already enabled
2390 return;
2391 }
2392
2393 mExtensions.*(extension.ExtensionsMember) = true;
2394 updateCaps();
2395 initExtensionStrings();
2396}
2397
2398size_t Context::getRequestableExtensionStringCount() const
2399{
2400 return mRequestableExtensionStrings.size();
2401}
2402
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002403void Context::beginTransformFeedback(GLenum primitiveMode)
2404{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002405 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002406 ASSERT(transformFeedback != nullptr);
2407 ASSERT(!transformFeedback->isPaused());
2408
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002409 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002410}
2411
2412bool Context::hasActiveTransformFeedback(GLuint program) const
2413{
2414 for (auto pair : mTransformFeedbackMap)
2415 {
2416 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2417 {
2418 return true;
2419 }
2420 }
2421 return false;
2422}
2423
Geoff Langc287ea62016-09-16 14:46:51 -04002424void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002425{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002426 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002427
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002428 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002429
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002430 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002431
Geoff Langeb66a6e2016-10-31 13:06:12 -04002432 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002433 {
2434 // Disable ES3+ extensions
2435 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002436 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002437 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002438 }
2439
Geoff Langeb66a6e2016-10-31 13:06:12 -04002440 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002441 {
2442 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2443 //mExtensions.sRGB = false;
2444 }
2445
Jamie Madill00ed7a12016-05-19 13:13:38 -04002446 // Some extensions are always available because they are implemented in the GL layer.
2447 mExtensions.bindUniformLocation = true;
2448 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002449 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002450 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002451
2452 // Enable the no error extension if the context was created with the flag.
2453 mExtensions.noError = mSkipValidation;
2454
Geoff Lang70d0f492015-12-10 17:45:46 -05002455 // Explicitly enable GL_KHR_debug
2456 mExtensions.debug = true;
2457 mExtensions.maxDebugMessageLength = 1024;
2458 mExtensions.maxDebugLoggedMessages = 1024;
2459 mExtensions.maxDebugGroupStackDepth = 1024;
2460 mExtensions.maxLabelLength = 1024;
2461
Geoff Langff5b2d52016-09-07 11:32:23 -04002462 // Explicitly enable GL_ANGLE_robust_client_memory
2463 mExtensions.robustClientMemory = true;
2464
Geoff Lang301d1612014-07-09 10:34:37 -04002465 // Apply implementation limits
2466 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002467 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2468 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2469
2470 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002471
Geoff Langc287ea62016-09-16 14:46:51 -04002472 // WebGL compatibility
2473 mExtensions.webglCompatibility = webGLContext;
2474 for (const auto &extensionInfo : GetExtensionInfoMap())
2475 {
2476 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002477 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002478 {
2479 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2480 }
2481 }
2482
2483 // Generate texture caps
2484 updateCaps();
2485}
2486
2487void Context::updateCaps()
2488{
Geoff Lang900013c2014-07-07 11:32:19 -04002489 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002490 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002491
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002492 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002493 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2494 {
2495 GLenum format = i->first;
2496 TextureCaps formatCaps = i->second;
2497
Geoff Lang5d601382014-07-22 15:14:06 -04002498 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002499
Geoff Lang0d8b7242015-09-09 14:56:53 -04002500 // Update the format caps based on the client version and extensions.
2501 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2502 // ES3.
2503 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002504 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002505 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002506 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002507 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002508 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002509
2510 // OpenGL ES does not support multisampling with integer formats
2511 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002512 {
Geoff Langd87878e2014-09-19 15:42:59 -04002513 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002514 }
Geoff Langd87878e2014-09-19 15:42:59 -04002515
2516 if (formatCaps.texturable && formatInfo.compressed)
2517 {
2518 mCaps.compressedTextureFormats.push_back(format);
2519 }
2520
2521 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002522 }
2523}
2524
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002525void Context::initWorkarounds()
2526{
2527 // Lose the context upon out of memory error if the application is
2528 // expecting to watch for those events.
2529 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2530}
2531
Jamie Madill1b94d432015-08-07 13:23:23 -04002532void Context::syncRendererState()
2533{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002534 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2535 mImplementation->syncState(mGLState, dirtyBits);
2536 mGLState.clearDirtyBits();
2537 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002538}
2539
Jamie Madillad9f24e2016-02-12 09:27:24 -05002540void Context::syncRendererState(const State::DirtyBits &bitMask,
2541 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002542{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002543 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2544 mImplementation->syncState(mGLState, dirtyBits);
2545 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002546
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002547 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002548}
Jamie Madillc29968b2016-01-20 11:17:23 -05002549
2550void Context::blitFramebuffer(GLint srcX0,
2551 GLint srcY0,
2552 GLint srcX1,
2553 GLint srcY1,
2554 GLint dstX0,
2555 GLint dstY0,
2556 GLint dstX1,
2557 GLint dstY1,
2558 GLbitfield mask,
2559 GLenum filter)
2560{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002561 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002562 ASSERT(drawFramebuffer);
2563
2564 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2565 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2566
Jamie Madillad9f24e2016-02-12 09:27:24 -05002567 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002568
Jamie Madill8415b5f2016-04-26 13:41:39 -04002569 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002570}
Jamie Madillc29968b2016-01-20 11:17:23 -05002571
2572void Context::clear(GLbitfield mask)
2573{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002574 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002575 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002576}
2577
2578void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2579{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002580 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002581 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2582 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002583}
2584
2585void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2586{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002587 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002588 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2589 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002590}
2591
2592void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2593{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002594 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002595 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2596 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002597}
2598
2599void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2600{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002601 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002602 ASSERT(framebufferObject);
2603
2604 // If a buffer is not present, the clear has no effect
2605 if (framebufferObject->getDepthbuffer() == nullptr &&
2606 framebufferObject->getStencilbuffer() == nullptr)
2607 {
2608 return;
2609 }
2610
Jamie Madillad9f24e2016-02-12 09:27:24 -05002611 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002612 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2613 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002614}
2615
2616void Context::readPixels(GLint x,
2617 GLint y,
2618 GLsizei width,
2619 GLsizei height,
2620 GLenum format,
2621 GLenum type,
2622 GLvoid *pixels)
2623{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002624 if (width == 0 || height == 0)
2625 {
2626 return;
2627 }
2628
Jamie Madillad9f24e2016-02-12 09:27:24 -05002629 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002630
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002631 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002632 ASSERT(framebufferObject);
2633
2634 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002635 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002636}
2637
2638void Context::copyTexImage2D(GLenum target,
2639 GLint level,
2640 GLenum internalformat,
2641 GLint x,
2642 GLint y,
2643 GLsizei width,
2644 GLsizei height,
2645 GLint border)
2646{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002647 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002648 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002649
Jamie Madillc29968b2016-01-20 11:17:23 -05002650 Rectangle sourceArea(x, y, width, height);
2651
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002652 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002653 Texture *texture =
2654 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002655 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002656}
2657
2658void Context::copyTexSubImage2D(GLenum target,
2659 GLint level,
2660 GLint xoffset,
2661 GLint yoffset,
2662 GLint x,
2663 GLint y,
2664 GLsizei width,
2665 GLsizei height)
2666{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002667 if (width == 0 || height == 0)
2668 {
2669 return;
2670 }
2671
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002672 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002673 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002674
Jamie Madillc29968b2016-01-20 11:17:23 -05002675 Offset destOffset(xoffset, yoffset, 0);
2676 Rectangle sourceArea(x, y, width, height);
2677
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002678 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002679 Texture *texture =
2680 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002681 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002682}
2683
2684void Context::copyTexSubImage3D(GLenum target,
2685 GLint level,
2686 GLint xoffset,
2687 GLint yoffset,
2688 GLint zoffset,
2689 GLint x,
2690 GLint y,
2691 GLsizei width,
2692 GLsizei height)
2693{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002694 if (width == 0 || height == 0)
2695 {
2696 return;
2697 }
2698
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002699 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002700 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002701
Jamie Madillc29968b2016-01-20 11:17:23 -05002702 Offset destOffset(xoffset, yoffset, zoffset);
2703 Rectangle sourceArea(x, y, width, height);
2704
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002705 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002706 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002707 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002708}
2709
2710void Context::framebufferTexture2D(GLenum target,
2711 GLenum attachment,
2712 GLenum textarget,
2713 GLuint texture,
2714 GLint level)
2715{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002716 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002717 ASSERT(framebuffer);
2718
2719 if (texture != 0)
2720 {
2721 Texture *textureObj = getTexture(texture);
2722
2723 ImageIndex index = ImageIndex::MakeInvalid();
2724
2725 if (textarget == GL_TEXTURE_2D)
2726 {
2727 index = ImageIndex::Make2D(level);
2728 }
2729 else
2730 {
2731 ASSERT(IsCubeMapTextureTarget(textarget));
2732 index = ImageIndex::MakeCube(textarget, level);
2733 }
2734
2735 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2736 }
2737 else
2738 {
2739 framebuffer->resetAttachment(attachment);
2740 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002741
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002742 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002743}
2744
2745void Context::framebufferRenderbuffer(GLenum target,
2746 GLenum attachment,
2747 GLenum renderbuffertarget,
2748 GLuint renderbuffer)
2749{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002750 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002751 ASSERT(framebuffer);
2752
2753 if (renderbuffer != 0)
2754 {
2755 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2756 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2757 renderbufferObject);
2758 }
2759 else
2760 {
2761 framebuffer->resetAttachment(attachment);
2762 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002763
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002764 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002765}
2766
2767void Context::framebufferTextureLayer(GLenum target,
2768 GLenum attachment,
2769 GLuint texture,
2770 GLint level,
2771 GLint layer)
2772{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002773 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002774 ASSERT(framebuffer);
2775
2776 if (texture != 0)
2777 {
2778 Texture *textureObject = getTexture(texture);
2779
2780 ImageIndex index = ImageIndex::MakeInvalid();
2781
2782 if (textureObject->getTarget() == GL_TEXTURE_3D)
2783 {
2784 index = ImageIndex::Make3D(level, layer);
2785 }
2786 else
2787 {
2788 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2789 index = ImageIndex::Make2DArray(level, layer);
2790 }
2791
2792 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2793 }
2794 else
2795 {
2796 framebuffer->resetAttachment(attachment);
2797 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002798
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002799 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002800}
2801
2802void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2803{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002804 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002805 ASSERT(framebuffer);
2806 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002807 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002808}
2809
2810void Context::readBuffer(GLenum mode)
2811{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002812 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002813 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002814 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002815}
2816
2817void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2818{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002819 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002820 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002821
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002822 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002823 ASSERT(framebuffer);
2824
2825 // The specification isn't clear what should be done when the framebuffer isn't complete.
2826 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002827 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002828}
2829
2830void Context::invalidateFramebuffer(GLenum target,
2831 GLsizei numAttachments,
2832 const GLenum *attachments)
2833{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002834 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002835 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002836
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002837 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002838 ASSERT(framebuffer);
2839
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002840 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002841 {
Jamie Madill437fa652016-05-03 15:13:24 -04002842 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002843 }
Jamie Madill437fa652016-05-03 15:13:24 -04002844
2845 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002846}
2847
2848void Context::invalidateSubFramebuffer(GLenum target,
2849 GLsizei numAttachments,
2850 const GLenum *attachments,
2851 GLint x,
2852 GLint y,
2853 GLsizei width,
2854 GLsizei height)
2855{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002856 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002857 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002858
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002859 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002860 ASSERT(framebuffer);
2861
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002862 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002863 {
Jamie Madill437fa652016-05-03 15:13:24 -04002864 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002865 }
Jamie Madill437fa652016-05-03 15:13:24 -04002866
2867 Rectangle area(x, y, width, height);
2868 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002869}
2870
Jamie Madill73a84962016-02-12 09:27:23 -05002871void Context::texImage2D(GLenum target,
2872 GLint level,
2873 GLint internalformat,
2874 GLsizei width,
2875 GLsizei height,
2876 GLint border,
2877 GLenum format,
2878 GLenum type,
2879 const GLvoid *pixels)
2880{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002881 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002882
2883 Extents size(width, height, 1);
2884 Texture *texture =
2885 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002886 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002887 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002888}
2889
2890void Context::texImage3D(GLenum target,
2891 GLint level,
2892 GLint internalformat,
2893 GLsizei width,
2894 GLsizei height,
2895 GLsizei depth,
2896 GLint border,
2897 GLenum format,
2898 GLenum type,
2899 const GLvoid *pixels)
2900{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002901 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002902
2903 Extents size(width, height, depth);
2904 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002905 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002906 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002907}
2908
2909void Context::texSubImage2D(GLenum target,
2910 GLint level,
2911 GLint xoffset,
2912 GLint yoffset,
2913 GLsizei width,
2914 GLsizei height,
2915 GLenum format,
2916 GLenum type,
2917 const GLvoid *pixels)
2918{
2919 // Zero sized uploads are valid but no-ops
2920 if (width == 0 || height == 0)
2921 {
2922 return;
2923 }
2924
Jamie Madillad9f24e2016-02-12 09:27:24 -05002925 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002926
2927 Box area(xoffset, yoffset, 0, width, height, 1);
2928 Texture *texture =
2929 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002930 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002931 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002932}
2933
2934void Context::texSubImage3D(GLenum target,
2935 GLint level,
2936 GLint xoffset,
2937 GLint yoffset,
2938 GLint zoffset,
2939 GLsizei width,
2940 GLsizei height,
2941 GLsizei depth,
2942 GLenum format,
2943 GLenum type,
2944 const GLvoid *pixels)
2945{
2946 // Zero sized uploads are valid but no-ops
2947 if (width == 0 || height == 0 || depth == 0)
2948 {
2949 return;
2950 }
2951
Jamie Madillad9f24e2016-02-12 09:27:24 -05002952 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002953
2954 Box area(xoffset, yoffset, zoffset, width, height, depth);
2955 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002956 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002957 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002958}
2959
2960void Context::compressedTexImage2D(GLenum target,
2961 GLint level,
2962 GLenum internalformat,
2963 GLsizei width,
2964 GLsizei height,
2965 GLint border,
2966 GLsizei imageSize,
2967 const GLvoid *data)
2968{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002969 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002970
2971 Extents size(width, height, 1);
2972 Texture *texture =
2973 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002974 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2975 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002976 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002977}
2978
2979void Context::compressedTexImage3D(GLenum target,
2980 GLint level,
2981 GLenum internalformat,
2982 GLsizei width,
2983 GLsizei height,
2984 GLsizei depth,
2985 GLint border,
2986 GLsizei imageSize,
2987 const GLvoid *data)
2988{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002989 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002990
2991 Extents size(width, height, depth);
2992 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002993 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2994 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002995 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002996}
2997
2998void Context::compressedTexSubImage2D(GLenum target,
2999 GLint level,
3000 GLint xoffset,
3001 GLint yoffset,
3002 GLsizei width,
3003 GLsizei height,
3004 GLenum format,
3005 GLsizei imageSize,
3006 const GLvoid *data)
3007{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003008 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003009
3010 Box area(xoffset, yoffset, 0, width, height, 1);
3011 Texture *texture =
3012 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003013 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3014 format, imageSize,
3015 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003016}
3017
3018void Context::compressedTexSubImage3D(GLenum target,
3019 GLint level,
3020 GLint xoffset,
3021 GLint yoffset,
3022 GLint zoffset,
3023 GLsizei width,
3024 GLsizei height,
3025 GLsizei depth,
3026 GLenum format,
3027 GLsizei imageSize,
3028 const GLvoid *data)
3029{
3030 // Zero sized uploads are valid but no-ops
3031 if (width == 0 || height == 0)
3032 {
3033 return;
3034 }
3035
Jamie Madillad9f24e2016-02-12 09:27:24 -05003036 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003037
3038 Box area(xoffset, yoffset, zoffset, width, height, depth);
3039 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003040 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3041 format, imageSize,
3042 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003043}
3044
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003045void Context::generateMipmap(GLenum target)
3046{
3047 Texture *texture = getTargetTexture(target);
3048 handleError(texture->generateMipmap());
3049}
3050
Geoff Lang97073d12016-04-20 10:42:34 -07003051void Context::copyTextureCHROMIUM(GLuint sourceId,
3052 GLuint destId,
3053 GLint internalFormat,
3054 GLenum destType,
3055 GLboolean unpackFlipY,
3056 GLboolean unpackPremultiplyAlpha,
3057 GLboolean unpackUnmultiplyAlpha)
3058{
3059 syncStateForTexImage();
3060
3061 gl::Texture *sourceTexture = getTexture(sourceId);
3062 gl::Texture *destTexture = getTexture(destId);
3063 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3064 unpackPremultiplyAlpha == GL_TRUE,
3065 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3066}
3067
3068void Context::copySubTextureCHROMIUM(GLuint sourceId,
3069 GLuint destId,
3070 GLint xoffset,
3071 GLint yoffset,
3072 GLint x,
3073 GLint y,
3074 GLsizei width,
3075 GLsizei height,
3076 GLboolean unpackFlipY,
3077 GLboolean unpackPremultiplyAlpha,
3078 GLboolean unpackUnmultiplyAlpha)
3079{
3080 // Zero sized copies are valid but no-ops
3081 if (width == 0 || height == 0)
3082 {
3083 return;
3084 }
3085
3086 syncStateForTexImage();
3087
3088 gl::Texture *sourceTexture = getTexture(sourceId);
3089 gl::Texture *destTexture = getTexture(destId);
3090 Offset offset(xoffset, yoffset, 0);
3091 Rectangle area(x, y, width, height);
3092 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3093 unpackPremultiplyAlpha == GL_TRUE,
3094 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3095}
3096
Geoff Lang47110bf2016-04-20 11:13:22 -07003097void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3098{
3099 syncStateForTexImage();
3100
3101 gl::Texture *sourceTexture = getTexture(sourceId);
3102 gl::Texture *destTexture = getTexture(destId);
3103 handleError(destTexture->copyCompressedTexture(sourceTexture));
3104}
3105
Geoff Lang496c02d2016-10-20 11:38:11 -07003106void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003107{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003108 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003109 ASSERT(buffer);
3110
Geoff Lang496c02d2016-10-20 11:38:11 -07003111 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003112}
3113
3114GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3115{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003116 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003117 ASSERT(buffer);
3118
3119 Error error = buffer->map(access);
3120 if (error.isError())
3121 {
Jamie Madill437fa652016-05-03 15:13:24 -04003122 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003123 return nullptr;
3124 }
3125
3126 return buffer->getMapPointer();
3127}
3128
3129GLboolean Context::unmapBuffer(GLenum target)
3130{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003131 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003132 ASSERT(buffer);
3133
3134 GLboolean result;
3135 Error error = buffer->unmap(&result);
3136 if (error.isError())
3137 {
Jamie Madill437fa652016-05-03 15:13:24 -04003138 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003139 return GL_FALSE;
3140 }
3141
3142 return result;
3143}
3144
3145GLvoid *Context::mapBufferRange(GLenum target,
3146 GLintptr offset,
3147 GLsizeiptr length,
3148 GLbitfield access)
3149{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003150 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003151 ASSERT(buffer);
3152
3153 Error error = buffer->mapRange(offset, length, access);
3154 if (error.isError())
3155 {
Jamie Madill437fa652016-05-03 15:13:24 -04003156 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003157 return nullptr;
3158 }
3159
3160 return buffer->getMapPointer();
3161}
3162
3163void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3164{
3165 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3166}
3167
Jamie Madillad9f24e2016-02-12 09:27:24 -05003168void Context::syncStateForReadPixels()
3169{
3170 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3171}
3172
3173void Context::syncStateForTexImage()
3174{
3175 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3176}
3177
3178void Context::syncStateForClear()
3179{
3180 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3181}
3182
3183void Context::syncStateForBlit()
3184{
3185 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3186}
3187
Jamie Madillc20ab272016-06-09 07:20:46 -07003188void Context::activeTexture(GLenum texture)
3189{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003190 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003191}
3192
3193void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3194{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003195 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003196}
3197
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003198void Context::blendEquation(GLenum mode)
3199{
3200 mGLState.setBlendEquation(mode, mode);
3201}
3202
Jamie Madillc20ab272016-06-09 07:20:46 -07003203void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3204{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003205 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003206}
3207
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003208void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3209{
3210 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3211}
3212
Jamie Madillc20ab272016-06-09 07:20:46 -07003213void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3214{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003215 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003216}
3217
3218void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3219{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003220 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003221}
3222
3223void Context::clearDepthf(GLclampf depth)
3224{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003225 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003226}
3227
3228void Context::clearStencil(GLint s)
3229{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003230 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003231}
3232
3233void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3234{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003235 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003236}
3237
3238void Context::cullFace(GLenum mode)
3239{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003240 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003241}
3242
3243void Context::depthFunc(GLenum func)
3244{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003245 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003246}
3247
3248void Context::depthMask(GLboolean flag)
3249{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003250 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003251}
3252
3253void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3254{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003255 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003256}
3257
3258void Context::disable(GLenum cap)
3259{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003260 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003261}
3262
3263void Context::disableVertexAttribArray(GLuint index)
3264{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003265 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003266}
3267
3268void Context::enable(GLenum cap)
3269{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003270 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003271}
3272
3273void Context::enableVertexAttribArray(GLuint index)
3274{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003275 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003276}
3277
3278void Context::frontFace(GLenum mode)
3279{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003280 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003281}
3282
3283void Context::hint(GLenum target, GLenum mode)
3284{
3285 switch (target)
3286 {
3287 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003288 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003289 break;
3290
3291 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003292 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003293 break;
3294
3295 default:
3296 UNREACHABLE();
3297 return;
3298 }
3299}
3300
3301void Context::lineWidth(GLfloat width)
3302{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003303 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003304}
3305
3306void Context::pixelStorei(GLenum pname, GLint param)
3307{
3308 switch (pname)
3309 {
3310 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003311 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003312 break;
3313
3314 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003315 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003316 break;
3317
3318 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003319 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003320 break;
3321
3322 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003323 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003324 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003325 break;
3326
3327 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003328 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003329 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003330 break;
3331
3332 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003333 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335 break;
3336
3337 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003338 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340 break;
3341
3342 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003343 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345 break;
3346
3347 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003348 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003350 break;
3351
3352 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003353 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003355 break;
3356
3357 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003358 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003359 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003360 break;
3361
3362 default:
3363 UNREACHABLE();
3364 return;
3365 }
3366}
3367
3368void Context::polygonOffset(GLfloat factor, GLfloat units)
3369{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003370 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003371}
3372
3373void Context::sampleCoverage(GLclampf value, GLboolean invert)
3374{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003375 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003376}
3377
3378void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3379{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003380 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003381}
3382
3383void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3384{
3385 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3386 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003387 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003388 }
3389
3390 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3391 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003392 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003393 }
3394}
3395
3396void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3397{
3398 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3399 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003400 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003401 }
3402
3403 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3404 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003405 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003406 }
3407}
3408
3409void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3410{
3411 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3412 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003414 }
3415
3416 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3417 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003418 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003419 }
3420}
3421
3422void Context::vertexAttrib1f(GLuint index, GLfloat x)
3423{
3424 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003425 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003426}
3427
3428void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3429{
3430 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003431 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003432}
3433
3434void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3435{
3436 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003437 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003438}
3439
3440void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3441{
3442 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003443 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003444}
3445
3446void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3447{
3448 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003449 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003450}
3451
3452void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3453{
3454 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003455 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003456}
3457
3458void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3459{
3460 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003461 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003462}
3463
3464void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3465{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003466 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003467}
3468
3469void Context::vertexAttribPointer(GLuint index,
3470 GLint size,
3471 GLenum type,
3472 GLboolean normalized,
3473 GLsizei stride,
3474 const GLvoid *ptr)
3475{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003476 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3477 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003478}
3479
3480void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3481{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003482 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003483}
3484
3485void Context::vertexAttribIPointer(GLuint index,
3486 GLint size,
3487 GLenum type,
3488 GLsizei stride,
3489 const GLvoid *pointer)
3490{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003491 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3492 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003493}
3494
3495void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3496{
3497 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003498 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003499}
3500
3501void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3502{
3503 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003504 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003505}
3506
3507void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3508{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003509 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003510}
3511
3512void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3513{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003514 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003515}
3516
3517void Context::debugMessageControl(GLenum source,
3518 GLenum type,
3519 GLenum severity,
3520 GLsizei count,
3521 const GLuint *ids,
3522 GLboolean enabled)
3523{
3524 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3526 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003527}
3528
3529void Context::debugMessageInsert(GLenum source,
3530 GLenum type,
3531 GLuint id,
3532 GLenum severity,
3533 GLsizei length,
3534 const GLchar *buf)
3535{
3536 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003538}
3539
3540void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3541{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003542 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003543}
3544
3545GLuint Context::getDebugMessageLog(GLuint count,
3546 GLsizei bufSize,
3547 GLenum *sources,
3548 GLenum *types,
3549 GLuint *ids,
3550 GLenum *severities,
3551 GLsizei *lengths,
3552 GLchar *messageLog)
3553{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003554 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3555 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003556}
3557
3558void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3559{
3560 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003561 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003562}
3563
3564void Context::popDebugGroup()
3565{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003566 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003567}
3568
Jamie Madill29639852016-09-02 15:00:09 -04003569void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3570{
3571 Buffer *buffer = mGLState.getTargetBuffer(target);
3572 ASSERT(buffer);
3573 handleError(buffer->bufferData(target, data, size, usage));
3574}
3575
3576void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3577{
3578 if (data == nullptr)
3579 {
3580 return;
3581 }
3582
3583 Buffer *buffer = mGLState.getTargetBuffer(target);
3584 ASSERT(buffer);
3585 handleError(buffer->bufferSubData(target, data, size, offset));
3586}
3587
Jamie Madillef300b12016-10-07 15:12:09 -04003588void Context::attachShader(GLuint program, GLuint shader)
3589{
3590 auto programObject = mResourceManager->getProgram(program);
3591 auto shaderObject = mResourceManager->getShader(shader);
3592 ASSERT(programObject && shaderObject);
3593 programObject->attachShader(shaderObject);
3594}
3595
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003596const Workarounds &Context::getWorkarounds() const
3597{
3598 return mWorkarounds;
3599}
3600
Jamie Madillb0817d12016-11-01 15:48:31 -04003601void Context::copyBufferSubData(GLenum readTarget,
3602 GLenum writeTarget,
3603 GLintptr readOffset,
3604 GLintptr writeOffset,
3605 GLsizeiptr size)
3606{
3607 // if size is zero, the copy is a successful no-op
3608 if (size == 0)
3609 {
3610 return;
3611 }
3612
3613 // TODO(jmadill): cache these.
3614 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3615 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3616
3617 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3618}
3619
Jamie Madill01a80ee2016-11-07 12:06:18 -05003620void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3621{
3622 Program *programObject = getProgram(program);
3623 // TODO(jmadill): Re-use this from the validation if possible.
3624 ASSERT(programObject);
3625 programObject->bindAttributeLocation(index, name);
3626}
3627
3628void Context::bindBuffer(GLenum target, GLuint buffer)
3629{
3630 switch (target)
3631 {
3632 case GL_ARRAY_BUFFER:
3633 bindArrayBuffer(buffer);
3634 break;
3635 case GL_ELEMENT_ARRAY_BUFFER:
3636 bindElementArrayBuffer(buffer);
3637 break;
3638 case GL_COPY_READ_BUFFER:
3639 bindCopyReadBuffer(buffer);
3640 break;
3641 case GL_COPY_WRITE_BUFFER:
3642 bindCopyWriteBuffer(buffer);
3643 break;
3644 case GL_PIXEL_PACK_BUFFER:
3645 bindPixelPackBuffer(buffer);
3646 break;
3647 case GL_PIXEL_UNPACK_BUFFER:
3648 bindPixelUnpackBuffer(buffer);
3649 break;
3650 case GL_UNIFORM_BUFFER:
3651 bindGenericUniformBuffer(buffer);
3652 break;
3653 case GL_TRANSFORM_FEEDBACK_BUFFER:
3654 bindGenericTransformFeedbackBuffer(buffer);
3655 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003656 case GL_ATOMIC_COUNTER_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;
3663 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003664 if (buffer != 0)
3665 {
3666 // Binding buffers to this binding point is not implemented yet.
3667 UNIMPLEMENTED();
3668 }
Geoff Lang3b573612016-10-31 14:08:10 -04003669 break;
3670 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003671 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003672 break;
3673 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003674 if (buffer != 0)
3675 {
3676 // Binding buffers to this binding point is not implemented yet.
3677 UNIMPLEMENTED();
3678 }
Geoff Lang3b573612016-10-31 14:08:10 -04003679 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003680
3681 default:
3682 UNREACHABLE();
3683 break;
3684 }
3685}
3686
3687void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3688{
3689 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3690 {
3691 bindReadFramebuffer(framebuffer);
3692 }
3693
3694 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3695 {
3696 bindDrawFramebuffer(framebuffer);
3697 }
3698}
3699
3700void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3701{
3702 ASSERT(target == GL_RENDERBUFFER);
3703 Renderbuffer *object =
3704 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
3705 mGLState.setRenderbufferBinding(object);
3706}
3707
Jamie Madillc29968b2016-01-20 11:17:23 -05003708} // namespace gl