blob: 66fe675a9f2d1b95576a9b32feff786a32546d98 [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"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050029#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/ResourceManager.h"
31#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050032#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050033#include "libANGLE/Texture.h"
34#include "libANGLE/TransformFeedback.h"
35#include "libANGLE/VertexArray.h"
36#include "libANGLE/formatutils.h"
37#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070038#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040039#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040040#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030041#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040042#include "libANGLE/queryutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000043
Geoff Langf6db0982015-08-25 13:04:00 -040044namespace
45{
46
Ian Ewell3ffd78b2016-01-22 16:09:42 -050047template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050048std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030049 GLsizei numPaths,
50 const void *paths,
51 GLuint pathBase)
52{
53 std::vector<gl::Path *> ret;
54 ret.reserve(numPaths);
55
56 const auto *nameArray = static_cast<const T *>(paths);
57
58 for (GLsizei i = 0; i < numPaths; ++i)
59 {
60 const GLuint pathName = nameArray[i] + pathBase;
61
62 ret.push_back(resourceManager.getPath(pathName));
63 }
64
65 return ret;
66}
67
Geoff Lang4ddf5af2016-12-01 14:30:44 -050068std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030069 GLsizei numPaths,
70 GLenum pathNameType,
71 const void *paths,
72 GLuint pathBase)
73{
74 switch (pathNameType)
75 {
76 case GL_UNSIGNED_BYTE:
77 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
78
79 case GL_BYTE:
80 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
81
82 case GL_UNSIGNED_SHORT:
83 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_SHORT:
86 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_INT:
89 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_INT:
92 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
93 }
94
95 UNREACHABLE();
96 return std::vector<gl::Path *>();
97}
98
99template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400100gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500101{
Geoff Lang2186c382016-10-14 10:54:54 -0400102 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500103
104 switch (pname)
105 {
106 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400107 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500108 case GL_QUERY_RESULT_AVAILABLE_EXT:
109 {
110 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400111 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500112 if (!error.isError())
113 {
Geoff Lang2186c382016-10-14 10:54:54 -0400114 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500115 }
116 return error;
117 }
118 default:
119 UNREACHABLE();
120 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
121 }
122}
123
Geoff Langf6db0982015-08-25 13:04:00 -0400124void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
125{
Geoff Lang1a683462015-09-29 15:09:59 -0400126 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400127 {
128 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
129 tfBufferIndex++)
130 {
131 const OffsetBindingPointer<gl::Buffer> &buffer =
132 transformFeedback->getIndexedBuffer(tfBufferIndex);
133 if (buffer.get() != nullptr)
134 {
135 buffer->onTransformFeedback();
136 }
137 }
138 }
139}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140
141// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300142EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500143{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400144 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500145}
146
Martin Radev1be913c2016-07-11 17:59:16 +0300147EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
148{
149 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
150}
151
Geoff Langeb66a6e2016-10-31 13:06:12 -0400152gl::Version GetClientVersion(const egl::AttributeMap &attribs)
153{
154 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
155}
156
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500157GLenum GetResetStrategy(const egl::AttributeMap &attribs)
158{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400159 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
160 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500161 switch (attrib)
162 {
163 case EGL_NO_RESET_NOTIFICATION:
164 return GL_NO_RESET_NOTIFICATION_EXT;
165 case EGL_LOSE_CONTEXT_ON_RESET:
166 return GL_LOSE_CONTEXT_ON_RESET_EXT;
167 default:
168 UNREACHABLE();
169 return GL_NONE;
170 }
171}
172
173bool GetRobustAccess(const egl::AttributeMap &attribs)
174{
Geoff Lang077f20a2016-11-01 10:08:02 -0400175 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
176 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
177 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500178}
179
180bool GetDebug(const egl::AttributeMap &attribs)
181{
Geoff Lang077f20a2016-11-01 10:08:02 -0400182 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
183 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184}
185
186bool GetNoError(const egl::AttributeMap &attribs)
187{
188 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
189}
190
Geoff Langc287ea62016-09-16 14:46:51 -0400191bool GetWebGLContext(const egl::AttributeMap &attribs)
192{
193 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
194}
195
Geoff Langf41a7152016-09-19 15:11:17 -0400196bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
197{
198 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
199}
200
Martin Radev9d901792016-07-15 15:58:58 +0300201std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
202{
203 std::string labelName;
204 if (label != nullptr)
205 {
206 size_t labelLength = length < 0 ? strlen(label) : length;
207 labelName = std::string(label, labelLength);
208 }
209 return labelName;
210}
211
212void GetObjectLabelBase(const std::string &objectLabel,
213 GLsizei bufSize,
214 GLsizei *length,
215 GLchar *label)
216{
217 size_t writeLength = objectLabel.length();
218 if (label != nullptr && bufSize > 0)
219 {
220 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
221 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
222 label[writeLength] = '\0';
223 }
224
225 if (length != nullptr)
226 {
227 *length = static_cast<GLsizei>(writeLength);
228 }
229}
230
Geoff Langf6db0982015-08-25 13:04:00 -0400231} // anonymous namespace
232
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000233namespace gl
234{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000235
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400236Context::Context(rx::EGLImplFactory *implFactory,
237 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400238 const Context *shareContext,
Corentin Wallezc295e512017-01-27 17:47:50 -0500239 const egl::AttributeMap &attribs,
240 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300241
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500242 : ValidationContext(shareContext,
243 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700244 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500245 mCaps,
246 mTextureCaps,
247 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500248 mLimitations,
249 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700250 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500251 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400252 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500253 mClientType(EGL_OPENGL_ES_API),
254 mHasBeenCurrent(false),
255 mContextLost(false),
256 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700257 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500258 mResetStrategy(GetResetStrategy(attribs)),
259 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500260 mCurrentSurface(nullptr),
261 mSurfacelessFramebuffer(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000262{
Geoff Lang077f20a2016-11-01 10:08:02 -0400263 if (mRobustAccess)
264 {
265 UNIMPLEMENTED();
266 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000267
Corentin Wallezc295e512017-01-27 17:47:50 -0500268 initCaps(GetWebGLContext(attribs), displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700269 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400270
Geoff Langeb66a6e2016-10-31 13:06:12 -0400271 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400272 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100273
Shannon Woods53a94a82014-06-24 15:20:36 -0400274 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400275
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276 // [OpenGL ES 2.0.24] section 3.7 page 83:
277 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
278 // and cube map texture state vectors respectively associated with them.
279 // In order that access to these initial textures not be lost, they are treated as texture
280 // objects all of whose names are 0.
281
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400282 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500283 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500284
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400285 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500286 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400287
Geoff Langeb66a6e2016-10-31 13:06:12 -0400288 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400289 {
290 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400291 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500292 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400296 }
Geoff Lang3b573612016-10-31 14:08:10 -0400297 if (getClientVersion() >= Version(3, 1))
298 {
299 Texture *zeroTexture2DMultisample =
300 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
301 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
302 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000303
Ian Ewellbda75592016-04-18 17:25:54 -0400304 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
305 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTextureExternal =
307 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400308 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
309 }
310
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700311 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500312
Jamie Madill57a89722013-07-02 11:57:03 -0400313 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000314 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800315 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000316 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400317
Jamie Madill01a80ee2016-11-07 12:06:18 -0500318 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000319
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000320 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500321 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000322 {
323 bindIndexedUniformBuffer(0, i, 0, -1);
324 }
325
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000326 bindCopyReadBuffer(0);
327 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000328 bindPixelPackBuffer(0);
329 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000330
Geoff Langeb66a6e2016-10-31 13:06:12 -0400331 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400332 {
333 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
334 // In the initial state, a default transform feedback object is bound and treated as
335 // a transform feedback object with a name of zero. That object is bound any time
336 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400337 bindTransformFeedback(0);
338 }
Geoff Langc8058452014-02-03 12:04:11 -0500339
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700340 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500341
342 // Initialize dirty bit masks
343 // TODO(jmadill): additional ES3 state
344 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
345 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
346 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
347 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
348 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
349 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400350 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500351 // No dirty objects.
352
353 // Readpixels uses the pack state and read FBO
354 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
355 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
356 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
357 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
358 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400359 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500360 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
361
362 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
363 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
364 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
365 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
366 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
367 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
368 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
369 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
370 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
371 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
372 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
373 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
374
375 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
376 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700377 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500378 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
379 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400380
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400381 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000382}
383
384Context::~Context()
385{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700386 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000387
Corentin Wallez80b24112015-08-25 16:41:57 -0400388 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000389 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400390 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000391 }
392
Corentin Wallez80b24112015-08-25 16:41:57 -0400393 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000394 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400395 if (query.second != nullptr)
396 {
397 query.second->release();
398 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000399 }
400
Corentin Wallez80b24112015-08-25 16:41:57 -0400401 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400402 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400403 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400404 }
405
Corentin Wallez80b24112015-08-25 16:41:57 -0400406 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500407 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500408 if (transformFeedback.second != nullptr)
409 {
410 transformFeedback.second->release();
411 }
Geoff Langc8058452014-02-03 12:04:11 -0500412 }
413
Jamie Madilldedd7b92014-11-05 16:30:36 -0500414 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400415 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500416 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400417 }
418 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000419
Corentin Wallezccab69d2017-01-27 16:57:15 -0500420 SafeDelete(mSurfacelessFramebuffer);
421
Corentin Wallezc295e512017-01-27 17:47:50 -0500422 releaseSurface();
Corentin Wallez51706ea2015-08-07 14:39:22 -0400423
Geoff Lang492a7e42014-11-05 13:27:06 -0500424 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000425}
426
daniel@transgaming.comad629872012-11-28 19:32:06 +0000427void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000428{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429 if (!mHasBeenCurrent)
430 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500432 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400433 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000434
Corentin Wallezc295e512017-01-27 17:47:50 -0500435 int width = 0;
436 int height = 0;
437 if (surface != nullptr)
438 {
439 width = surface->getWidth();
440 height = surface->getHeight();
441 }
442
443 mGLState.setViewportParams(0, 0, width, height);
444 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000445
446 mHasBeenCurrent = true;
447 }
448
Jamie Madill1b94d432015-08-07 13:23:23 -0400449 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700450 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400451
Corentin Wallezc295e512017-01-27 17:47:50 -0500452 releaseSurface();
Corentin Wallezccab69d2017-01-27 16:57:15 -0500453
454 Framebuffer *newDefault = nullptr;
455 if (surface != nullptr)
456 {
457 surface->setIsCurrent(true);
458 mCurrentSurface = surface;
459 newDefault = surface->getDefaultFramebuffer();
460 }
461 else
462 {
463 if (mSurfacelessFramebuffer == nullptr)
464 {
465 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
466 }
467
468 newDefault = mSurfacelessFramebuffer;
469 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000470
Corentin Wallez37c39792015-08-20 14:19:46 -0400471 // Update default framebuffer, the binding of the previous default
472 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400473 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700474 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400475 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700476 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400477 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700478 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400479 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700480 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400481 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500482 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400483 }
Ian Ewell292f0052016-02-04 10:37:32 -0500484
485 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700486 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000487}
488
Jamie Madill77a72f62015-04-14 11:18:32 -0400489void Context::releaseSurface()
490{
Corentin Wallez37c39792015-08-20 14:19:46 -0400491 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500492 Framebuffer *currentDefault = nullptr;
493 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400494 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500495 currentDefault = mCurrentSurface->getDefaultFramebuffer();
496 }
497 else if (mSurfacelessFramebuffer != nullptr)
498 {
499 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400500 }
501
Corentin Wallezc295e512017-01-27 17:47:50 -0500502 if (mGLState.getReadFramebuffer() == currentDefault)
503 {
504 mGLState.setReadFramebufferBinding(nullptr);
505 }
506 if (mGLState.getDrawFramebuffer() == currentDefault)
507 {
508 mGLState.setDrawFramebufferBinding(nullptr);
509 }
510 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
511
512 if (mCurrentSurface)
513 {
514 mCurrentSurface->setIsCurrent(false);
515 mCurrentSurface = nullptr;
516 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400517}
518
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000519GLuint Context::createBuffer()
520{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500521 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000522}
523
524GLuint Context::createProgram()
525{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500526 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000527}
528
529GLuint Context::createShader(GLenum type)
530{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500531 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000532}
533
534GLuint Context::createTexture()
535{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500536 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000537}
538
539GLuint Context::createRenderbuffer()
540{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500541 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000542}
543
Geoff Lang882033e2014-09-30 11:26:07 -0400544GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400545{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500546 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400547
Cooper Partind8e62a32015-01-29 15:21:25 -0800548 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400549}
550
Sami Väisänene45e53b2016-05-25 10:36:04 +0300551GLuint Context::createPaths(GLsizei range)
552{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500553 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300554 if (resultOrError.isError())
555 {
556 handleError(resultOrError.getError());
557 return 0;
558 }
559 return resultOrError.getResult();
560}
561
Jamie Madill57a89722013-07-02 11:57:03 -0400562GLuint Context::createVertexArray()
563{
Geoff Lang36167ab2015-12-07 10:27:14 -0500564 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
565 mVertexArrayMap[vertexArray] = nullptr;
566 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400567}
568
Jamie Madilldc356042013-07-19 16:36:57 -0400569GLuint Context::createSampler()
570{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500571 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400572}
573
Geoff Langc8058452014-02-03 12:04:11 -0500574GLuint Context::createTransformFeedback()
575{
Geoff Lang36167ab2015-12-07 10:27:14 -0500576 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
577 mTransformFeedbackMap[transformFeedback] = nullptr;
578 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500579}
580
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000581// Returns an unused framebuffer name
582GLuint Context::createFramebuffer()
583{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500584 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585}
586
Jamie Madill33dc8432013-07-26 11:55:05 -0400587GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000588{
Jamie Madill33dc8432013-07-26 11:55:05 -0400589 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000590
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400591 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592
593 return handle;
594}
595
596// Returns an unused query name
597GLuint Context::createQuery()
598{
599 GLuint handle = mQueryHandleAllocator.allocate();
600
601 mQueryMap[handle] = NULL;
602
603 return handle;
604}
605
606void Context::deleteBuffer(GLuint buffer)
607{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500608 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000609 {
610 detachBuffer(buffer);
611 }
Jamie Madill893ab082014-05-16 16:56:10 -0400612
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500613 mState.mBuffers->deleteBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000614}
615
616void Context::deleteShader(GLuint shader)
617{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500618 mState.mShaderPrograms->deleteShader(shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000619}
620
621void Context::deleteProgram(GLuint program)
622{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500623 mState.mShaderPrograms->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000624}
625
626void Context::deleteTexture(GLuint texture)
627{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500628 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629 {
630 detachTexture(texture);
631 }
632
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500633 mState.mTextures->deleteTexture(texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000634}
635
636void Context::deleteRenderbuffer(GLuint renderbuffer)
637{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500638 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000639 {
640 detachRenderbuffer(renderbuffer);
641 }
Jamie Madill893ab082014-05-16 16:56:10 -0400642
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500643 mState.mRenderbuffers->deleteRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000644}
645
Jamie Madillcd055f82013-07-26 11:55:15 -0400646void Context::deleteFenceSync(GLsync fenceSync)
647{
648 // The spec specifies the underlying Fence object is not deleted until all current
649 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
650 // and since our API is currently designed for being called from a single thread, we can delete
651 // the fence immediately.
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500652 mState.mFenceSyncs->deleteFenceSync(
653 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400654}
655
Sami Väisänene45e53b2016-05-25 10:36:04 +0300656void Context::deletePaths(GLuint first, GLsizei range)
657{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500658 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300659}
660
661bool Context::hasPathData(GLuint path) const
662{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500663 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300664 if (pathObj == nullptr)
665 return false;
666
667 return pathObj->hasPathData();
668}
669
670bool Context::hasPath(GLuint path) const
671{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500672 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300673}
674
675void Context::setPathCommands(GLuint path,
676 GLsizei numCommands,
677 const GLubyte *commands,
678 GLsizei numCoords,
679 GLenum coordType,
680 const void *coords)
681{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500682 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300683
684 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
685}
686
687void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
688{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500689 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300690
691 switch (pname)
692 {
693 case GL_PATH_STROKE_WIDTH_CHROMIUM:
694 pathObj->setStrokeWidth(value);
695 break;
696 case GL_PATH_END_CAPS_CHROMIUM:
697 pathObj->setEndCaps(static_cast<GLenum>(value));
698 break;
699 case GL_PATH_JOIN_STYLE_CHROMIUM:
700 pathObj->setJoinStyle(static_cast<GLenum>(value));
701 break;
702 case GL_PATH_MITER_LIMIT_CHROMIUM:
703 pathObj->setMiterLimit(value);
704 break;
705 case GL_PATH_STROKE_BOUND_CHROMIUM:
706 pathObj->setStrokeBound(value);
707 break;
708 default:
709 UNREACHABLE();
710 break;
711 }
712}
713
714void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
715{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500716 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300717
718 switch (pname)
719 {
720 case GL_PATH_STROKE_WIDTH_CHROMIUM:
721 *value = pathObj->getStrokeWidth();
722 break;
723 case GL_PATH_END_CAPS_CHROMIUM:
724 *value = static_cast<GLfloat>(pathObj->getEndCaps());
725 break;
726 case GL_PATH_JOIN_STYLE_CHROMIUM:
727 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
728 break;
729 case GL_PATH_MITER_LIMIT_CHROMIUM:
730 *value = pathObj->getMiterLimit();
731 break;
732 case GL_PATH_STROKE_BOUND_CHROMIUM:
733 *value = pathObj->getStrokeBound();
734 break;
735 default:
736 UNREACHABLE();
737 break;
738 }
739}
740
741void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
742{
743 mGLState.setPathStencilFunc(func, ref, mask);
744}
745
Jamie Madill57a89722013-07-02 11:57:03 -0400746void Context::deleteVertexArray(GLuint vertexArray)
747{
Geoff Lang36167ab2015-12-07 10:27:14 -0500748 auto iter = mVertexArrayMap.find(vertexArray);
749 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000750 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500751 VertexArray *vertexArrayObject = iter->second;
752 if (vertexArrayObject != nullptr)
753 {
754 detachVertexArray(vertexArray);
755 delete vertexArrayObject;
756 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000757
Geoff Lang36167ab2015-12-07 10:27:14 -0500758 mVertexArrayMap.erase(iter);
759 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400760 }
761}
762
Jamie Madilldc356042013-07-19 16:36:57 -0400763void Context::deleteSampler(GLuint sampler)
764{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500765 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400766 {
767 detachSampler(sampler);
768 }
769
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500770 mState.mSamplers->deleteSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400771}
772
Geoff Langc8058452014-02-03 12:04:11 -0500773void Context::deleteTransformFeedback(GLuint transformFeedback)
774{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500775 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500776 if (iter != mTransformFeedbackMap.end())
777 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500778 TransformFeedback *transformFeedbackObject = iter->second;
779 if (transformFeedbackObject != nullptr)
780 {
781 detachTransformFeedback(transformFeedback);
782 transformFeedbackObject->release();
783 }
784
Geoff Lang50b3fe82015-12-08 14:49:12 +0000785 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500786 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500787 }
788}
789
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000790void Context::deleteFramebuffer(GLuint framebuffer)
791{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500792 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793 {
794 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500796
797 mState.mFramebuffers->deleteFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798}
799
Jamie Madill33dc8432013-07-26 11:55:05 -0400800void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500802 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000803
Jamie Madill33dc8432013-07-26 11:55:05 -0400804 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400806 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000807 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400808 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000809 }
810}
811
812void Context::deleteQuery(GLuint query)
813{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500814 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815 if (queryObject != mQueryMap.end())
816 {
817 mQueryHandleAllocator.release(queryObject->first);
818 if (queryObject->second)
819 {
820 queryObject->second->release();
821 }
822 mQueryMap.erase(queryObject);
823 }
824}
825
Geoff Lang70d0f492015-12-10 17:45:46 -0500826Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000827{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500828 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000829}
830
Jamie Madill570f7c82014-07-03 10:38:54 -0400831Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000832{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500833 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000834}
835
Geoff Lang70d0f492015-12-10 17:45:46 -0500836Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500838 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000839}
840
Jamie Madillcd055f82013-07-26 11:55:15 -0400841FenceSync *Context::getFenceSync(GLsync handle) const
842{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500843 return mState.mFenceSyncs->getFenceSync(
844 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400845}
846
Jamie Madill57a89722013-07-02 11:57:03 -0400847VertexArray *Context::getVertexArray(GLuint handle) const
848{
849 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500850 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400851}
852
Jamie Madilldc356042013-07-19 16:36:57 -0400853Sampler *Context::getSampler(GLuint handle) const
854{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500855 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400856}
857
Geoff Langc8058452014-02-03 12:04:11 -0500858TransformFeedback *Context::getTransformFeedback(GLuint handle) const
859{
Geoff Lang36167ab2015-12-07 10:27:14 -0500860 auto iter = mTransformFeedbackMap.find(handle);
861 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500862}
863
Geoff Lang70d0f492015-12-10 17:45:46 -0500864LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
865{
866 switch (identifier)
867 {
868 case GL_BUFFER:
869 return getBuffer(name);
870 case GL_SHADER:
871 return getShader(name);
872 case GL_PROGRAM:
873 return getProgram(name);
874 case GL_VERTEX_ARRAY:
875 return getVertexArray(name);
876 case GL_QUERY:
877 return getQuery(name);
878 case GL_TRANSFORM_FEEDBACK:
879 return getTransformFeedback(name);
880 case GL_SAMPLER:
881 return getSampler(name);
882 case GL_TEXTURE:
883 return getTexture(name);
884 case GL_RENDERBUFFER:
885 return getRenderbuffer(name);
886 case GL_FRAMEBUFFER:
887 return getFramebuffer(name);
888 default:
889 UNREACHABLE();
890 return nullptr;
891 }
892}
893
894LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
895{
896 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
897}
898
Martin Radev9d901792016-07-15 15:58:58 +0300899void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
900{
901 LabeledObject *object = getLabeledObject(identifier, name);
902 ASSERT(object != nullptr);
903
904 std::string labelName = GetObjectLabelFromPointer(length, label);
905 object->setLabel(labelName);
906}
907
908void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
909{
910 LabeledObject *object = getLabeledObjectFromPtr(ptr);
911 ASSERT(object != nullptr);
912
913 std::string labelName = GetObjectLabelFromPointer(length, label);
914 object->setLabel(labelName);
915}
916
917void Context::getObjectLabel(GLenum identifier,
918 GLuint name,
919 GLsizei bufSize,
920 GLsizei *length,
921 GLchar *label) const
922{
923 LabeledObject *object = getLabeledObject(identifier, name);
924 ASSERT(object != nullptr);
925
926 const std::string &objectLabel = object->getLabel();
927 GetObjectLabelBase(objectLabel, bufSize, length, label);
928}
929
930void Context::getObjectPtrLabel(const void *ptr,
931 GLsizei bufSize,
932 GLsizei *length,
933 GLchar *label) const
934{
935 LabeledObject *object = getLabeledObjectFromPtr(ptr);
936 ASSERT(object != nullptr);
937
938 const std::string &objectLabel = object->getLabel();
939 GetObjectLabelBase(objectLabel, bufSize, length, label);
940}
941
Jamie Madilldc356042013-07-19 16:36:57 -0400942bool Context::isSampler(GLuint samplerName) const
943{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500944 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400945}
946
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500947void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500949 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700950 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000951}
952
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800953void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
954{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500955 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800956 mGLState.setDrawIndirectBufferBinding(buffer);
957}
958
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500959void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000960{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500961 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700962 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000963}
964
Jamie Madilldedd7b92014-11-05 16:30:36 -0500965void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000966{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500967 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000968
Jamie Madilldedd7b92014-11-05 16:30:36 -0500969 if (handle == 0)
970 {
971 texture = mZeroTextures[target].get();
972 }
973 else
974 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500975 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500976 }
977
978 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700979 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000980}
981
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500982void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000983{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500984 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
985 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700986 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987}
988
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500989void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000990{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500991 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
992 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700993 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000994}
995
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500996void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400997{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500998 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700999 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001000}
1001
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001002void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001003{
Geoff Lang76b10c92014-09-05 16:28:14 -04001004 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001005 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001006 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001007 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001008}
1009
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001010void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001011{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001012 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001013 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001014}
1015
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001016void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1017 GLuint index,
1018 GLintptr offset,
1019 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001020{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001021 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001022 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001023}
1024
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001025void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001026{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001027 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001028 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001029}
1030
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001031void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1032 GLuint index,
1033 GLintptr offset,
1034 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001035{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001036 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001037 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001038}
1039
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001040void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001041{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001042 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001043 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001044}
1045
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001046void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001047{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001048 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001049 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001050}
1051
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001052void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001053{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001054 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001055 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001056}
1057
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001058void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001059{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001060 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001061 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001062}
1063
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001064void Context::useProgram(GLuint program)
1065{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001066 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001067}
1068
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001069void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001070{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001071 TransformFeedback *transformFeedback =
1072 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001073 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001074}
1075
Geoff Lang5aad9672014-09-08 11:10:42 -04001076Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001078 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001079 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001080
Geoff Lang5aad9672014-09-08 11:10:42 -04001081 // begin query
1082 Error error = queryObject->begin();
1083 if (error.isError())
1084 {
1085 return error;
1086 }
1087
1088 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001089 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001090
He Yunchaoacd18982017-01-04 10:46:42 +08001091 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001092}
1093
Geoff Lang5aad9672014-09-08 11:10:42 -04001094Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001096 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001097 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001098
Geoff Lang5aad9672014-09-08 11:10:42 -04001099 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001100
Geoff Lang5aad9672014-09-08 11:10:42 -04001101 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001102 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001103
1104 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001105}
1106
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001107Error Context::queryCounter(GLuint id, GLenum target)
1108{
1109 ASSERT(target == GL_TIMESTAMP_EXT);
1110
1111 Query *queryObject = getQuery(id, true, target);
1112 ASSERT(queryObject);
1113
1114 return queryObject->queryCounter();
1115}
1116
1117void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1118{
1119 switch (pname)
1120 {
1121 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001122 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001123 break;
1124 case GL_QUERY_COUNTER_BITS_EXT:
1125 switch (target)
1126 {
1127 case GL_TIME_ELAPSED_EXT:
1128 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1129 break;
1130 case GL_TIMESTAMP_EXT:
1131 params[0] = getExtensions().queryCounterBitsTimestamp;
1132 break;
1133 default:
1134 UNREACHABLE();
1135 params[0] = 0;
1136 break;
1137 }
1138 break;
1139 default:
1140 UNREACHABLE();
1141 return;
1142 }
1143}
1144
Geoff Lang2186c382016-10-14 10:54:54 -04001145void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001146{
Geoff Lang2186c382016-10-14 10:54:54 -04001147 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001148}
1149
Geoff Lang2186c382016-10-14 10:54:54 -04001150void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001151{
Geoff Lang2186c382016-10-14 10:54:54 -04001152 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001153}
1154
Geoff Lang2186c382016-10-14 10:54:54 -04001155void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001156{
Geoff Lang2186c382016-10-14 10:54:54 -04001157 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001158}
1159
Geoff Lang2186c382016-10-14 10:54:54 -04001160void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001161{
Geoff Lang2186c382016-10-14 10:54:54 -04001162 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001163}
1164
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001165Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001166{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001167 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001168}
1169
Jamie Madill33dc8432013-07-26 11:55:05 -04001170FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001172 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173
Jamie Madill33dc8432013-07-26 11:55:05 -04001174 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175 {
1176 return NULL;
1177 }
1178 else
1179 {
1180 return fence->second;
1181 }
1182}
1183
1184Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1185{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001186 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187
1188 if (query == mQueryMap.end())
1189 {
1190 return NULL;
1191 }
1192 else
1193 {
1194 if (!query->second && create)
1195 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001196 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197 query->second->addRef();
1198 }
1199 return query->second;
1200 }
1201}
1202
Geoff Lang70d0f492015-12-10 17:45:46 -05001203Query *Context::getQuery(GLuint handle) const
1204{
1205 auto iter = mQueryMap.find(handle);
1206 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1207}
1208
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001209Texture *Context::getTargetTexture(GLenum target) const
1210{
Ian Ewellbda75592016-04-18 17:25:54 -04001211 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001212 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001213}
1214
Geoff Lang76b10c92014-09-05 16:28:14 -04001215Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001217 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218}
1219
Geoff Lang492a7e42014-11-05 13:27:06 -05001220Compiler *Context::getCompiler() const
1221{
1222 return mCompiler;
1223}
1224
Jamie Madill893ab082014-05-16 16:56:10 -04001225void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226{
1227 switch (pname)
1228 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001229 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001230 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001231 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001232 mGLState.getBooleanv(pname, params);
1233 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001234 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235}
1236
Jamie Madill893ab082014-05-16 16:56:10 -04001237void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238{
Shannon Woods53a94a82014-06-24 15:20:36 -04001239 // Queries about context capabilities and maximums are answered by Context.
1240 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241 switch (pname)
1242 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001244 params[0] = mCaps.minAliasedLineWidth;
1245 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246 break;
1247 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001248 params[0] = mCaps.minAliasedPointSize;
1249 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001251 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001252 ASSERT(mExtensions.textureFilterAnisotropic);
1253 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001254 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001255 case GL_MAX_TEXTURE_LOD_BIAS:
1256 *params = mCaps.maxLODBias;
1257 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001258
1259 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1260 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1261 {
1262 ASSERT(mExtensions.pathRendering);
1263 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1264 memcpy(params, m, 16 * sizeof(GLfloat));
1265 }
1266 break;
1267
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001269 mGLState.getFloatv(pname, params);
1270 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272}
1273
Jamie Madill893ab082014-05-16 16:56:10 -04001274void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275{
Shannon Woods53a94a82014-06-24 15:20:36 -04001276 // Queries about context capabilities and maximums are answered by Context.
1277 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001278
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279 switch (pname)
1280 {
Geoff Lang301d1612014-07-09 10:34:37 -04001281 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1282 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1283 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001284 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1285 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1286 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001287 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1288 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1289 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001290 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001291 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1292 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1293 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001294 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001295 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001296 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1297 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1298 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1299 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001300 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1301 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001302 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1303 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001304 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001305 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1306 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1307 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1308 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001309 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001310 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001311 break;
1312 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001313 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001314 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001315 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1316 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001317 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1318 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1319 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001320 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1321 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1322 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001323 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324 case GL_MAX_VIEWPORT_DIMS:
1325 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001326 params[0] = mCaps.maxViewportWidth;
1327 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 }
1329 break;
1330 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001331 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001333 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1334 *params = mResetStrategy;
1335 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001336 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001337 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001338 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001339 case GL_SHADER_BINARY_FORMATS:
1340 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1341 break;
1342 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001343 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001344 break;
1345 case GL_PROGRAM_BINARY_FORMATS:
1346 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001347 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001348 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001349 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001350 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001351
1352 // GL_KHR_debug
1353 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1354 *params = mExtensions.maxDebugMessageLength;
1355 break;
1356 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1357 *params = mExtensions.maxDebugLoggedMessages;
1358 break;
1359 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1360 *params = mExtensions.maxDebugGroupStackDepth;
1361 break;
1362 case GL_MAX_LABEL_LENGTH:
1363 *params = mExtensions.maxLabelLength;
1364 break;
1365
Ian Ewell53f59f42016-01-28 17:36:55 -05001366 // GL_EXT_disjoint_timer_query
1367 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001368 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001369 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001370 case GL_MAX_FRAMEBUFFER_WIDTH:
1371 *params = mCaps.maxFramebufferWidth;
1372 break;
1373 case GL_MAX_FRAMEBUFFER_HEIGHT:
1374 *params = mCaps.maxFramebufferHeight;
1375 break;
1376 case GL_MAX_FRAMEBUFFER_SAMPLES:
1377 *params = mCaps.maxFramebufferSamples;
1378 break;
1379 case GL_MAX_SAMPLE_MASK_WORDS:
1380 *params = mCaps.maxSampleMaskWords;
1381 break;
1382 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1383 *params = mCaps.maxColorTextureSamples;
1384 break;
1385 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1386 *params = mCaps.maxDepthTextureSamples;
1387 break;
1388 case GL_MAX_INTEGER_SAMPLES:
1389 *params = mCaps.maxIntegerSamples;
1390 break;
1391 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1392 *params = mCaps.maxVertexAttribRelativeOffset;
1393 break;
1394 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1395 *params = mCaps.maxVertexAttribBindings;
1396 break;
1397 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1398 *params = mCaps.maxVertexAttribStride;
1399 break;
1400 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1401 *params = mCaps.maxVertexAtomicCounterBuffers;
1402 break;
1403 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1404 *params = mCaps.maxVertexAtomicCounters;
1405 break;
1406 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1407 *params = mCaps.maxVertexImageUniforms;
1408 break;
1409 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1410 *params = mCaps.maxVertexShaderStorageBlocks;
1411 break;
1412 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1413 *params = mCaps.maxFragmentAtomicCounterBuffers;
1414 break;
1415 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1416 *params = mCaps.maxFragmentAtomicCounters;
1417 break;
1418 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1419 *params = mCaps.maxFragmentImageUniforms;
1420 break;
1421 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1422 *params = mCaps.maxFragmentShaderStorageBlocks;
1423 break;
1424 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1425 *params = mCaps.minProgramTextureGatherOffset;
1426 break;
1427 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1428 *params = mCaps.maxProgramTextureGatherOffset;
1429 break;
1430 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1431 *params = mCaps.maxComputeWorkGroupInvocations;
1432 break;
1433 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1434 *params = mCaps.maxComputeUniformBlocks;
1435 break;
1436 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1437 *params = mCaps.maxComputeTextureImageUnits;
1438 break;
1439 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1440 *params = mCaps.maxComputeSharedMemorySize;
1441 break;
1442 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1443 *params = mCaps.maxComputeUniformComponents;
1444 break;
1445 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1446 *params = mCaps.maxComputeAtomicCounterBuffers;
1447 break;
1448 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1449 *params = mCaps.maxComputeAtomicCounters;
1450 break;
1451 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1452 *params = mCaps.maxComputeImageUniforms;
1453 break;
1454 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1455 *params = mCaps.maxCombinedComputeUniformComponents;
1456 break;
1457 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1458 *params = mCaps.maxComputeShaderStorageBlocks;
1459 break;
1460 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1461 *params = mCaps.maxCombinedShaderOutputResources;
1462 break;
1463 case GL_MAX_UNIFORM_LOCATIONS:
1464 *params = mCaps.maxUniformLocations;
1465 break;
1466 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1467 *params = mCaps.maxAtomicCounterBufferBindings;
1468 break;
1469 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1470 *params = mCaps.maxAtomicCounterBufferSize;
1471 break;
1472 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1473 *params = mCaps.maxCombinedAtomicCounterBuffers;
1474 break;
1475 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1476 *params = mCaps.maxCombinedAtomicCounters;
1477 break;
1478 case GL_MAX_IMAGE_UNITS:
1479 *params = mCaps.maxImageUnits;
1480 break;
1481 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1482 *params = mCaps.maxCombinedImageUniforms;
1483 break;
1484 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1485 *params = mCaps.maxShaderStorageBufferBindings;
1486 break;
1487 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1488 *params = mCaps.maxCombinedShaderStorageBlocks;
1489 break;
1490 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1491 *params = mCaps.shaderStorageBufferOffsetAlignment;
1492 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001493 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001494 mGLState.getIntegerv(mState, pname, params);
1495 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001496 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001497}
1498
Jamie Madill893ab082014-05-16 16:56:10 -04001499void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001500{
Shannon Woods53a94a82014-06-24 15:20:36 -04001501 // Queries about context capabilities and maximums are answered by Context.
1502 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001503 switch (pname)
1504 {
1505 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001506 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001507 break;
1508 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001509 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001510 break;
1511 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001512 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001513 break;
1514 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001515 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001516 break;
1517 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001518 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001519 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001520
1521 // GL_EXT_disjoint_timer_query
1522 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001523 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001524 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001525
1526 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1527 *params = mCaps.maxShaderStorageBlockSize;
1528 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001529 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001530 UNREACHABLE();
1531 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001532 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001533}
1534
Geoff Lang70d0f492015-12-10 17:45:46 -05001535void Context::getPointerv(GLenum pname, void **params) const
1536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001537 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001538}
1539
Martin Radev66fb8202016-07-28 11:45:20 +03001540void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001541{
Shannon Woods53a94a82014-06-24 15:20:36 -04001542 // Queries about context capabilities and maximums are answered by Context.
1543 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001544
1545 GLenum nativeType;
1546 unsigned int numParams;
1547 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1548 ASSERT(queryStatus);
1549
1550 if (nativeType == GL_INT)
1551 {
1552 switch (target)
1553 {
1554 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1555 ASSERT(index < 3u);
1556 *data = mCaps.maxComputeWorkGroupCount[index];
1557 break;
1558 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1559 ASSERT(index < 3u);
1560 *data = mCaps.maxComputeWorkGroupSize[index];
1561 break;
1562 default:
1563 mGLState.getIntegeri_v(target, index, data);
1564 }
1565 }
1566 else
1567 {
1568 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1569 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001570}
1571
Martin Radev66fb8202016-07-28 11:45:20 +03001572void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001573{
Shannon Woods53a94a82014-06-24 15:20:36 -04001574 // Queries about context capabilities and maximums are answered by Context.
1575 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001576
1577 GLenum nativeType;
1578 unsigned int numParams;
1579 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1580 ASSERT(queryStatus);
1581
1582 if (nativeType == GL_INT_64_ANGLEX)
1583 {
1584 mGLState.getInteger64i_v(target, index, data);
1585 }
1586 else
1587 {
1588 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1589 }
1590}
1591
1592void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1593{
1594 // Queries about context capabilities and maximums are answered by Context.
1595 // Queries about current GL state values are answered by State.
1596
1597 GLenum nativeType;
1598 unsigned int numParams;
1599 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1600 ASSERT(queryStatus);
1601
1602 if (nativeType == GL_BOOL)
1603 {
1604 mGLState.getBooleani_v(target, index, data);
1605 }
1606 else
1607 {
1608 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1609 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001610}
1611
Jamie Madill675fe712016-12-19 13:07:54 -05001612void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001613{
Jamie Madill1b94d432015-08-07 13:23:23 -04001614 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001615 auto error = mImplementation->drawArrays(mode, first, count);
1616 handleError(error);
1617 if (!error.isError())
1618 {
1619 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1620 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001621}
1622
Jamie Madill675fe712016-12-19 13:07:54 -05001623void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001624{
1625 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001626 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1627 handleError(error);
1628 if (!error.isError())
1629 {
1630 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1631 }
Geoff Langf6db0982015-08-25 13:04:00 -04001632}
1633
Jamie Madill675fe712016-12-19 13:07:54 -05001634void Context::drawElements(GLenum mode,
1635 GLsizei count,
1636 GLenum type,
1637 const GLvoid *indices,
1638 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001639{
Jamie Madill1b94d432015-08-07 13:23:23 -04001640 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001641 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001642}
1643
Jamie Madill675fe712016-12-19 13:07:54 -05001644void Context::drawElementsInstanced(GLenum mode,
1645 GLsizei count,
1646 GLenum type,
1647 const GLvoid *indices,
1648 GLsizei instances,
1649 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001650{
1651 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001652 handleError(
1653 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001654}
1655
Jamie Madill675fe712016-12-19 13:07:54 -05001656void Context::drawRangeElements(GLenum mode,
1657 GLuint start,
1658 GLuint end,
1659 GLsizei count,
1660 GLenum type,
1661 const GLvoid *indices,
1662 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001663{
1664 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001665 handleError(
1666 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001667}
1668
Jiajia Qind9671222016-11-29 16:30:31 +08001669void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1670{
1671 syncRendererState();
1672 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1673}
1674
1675void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1676{
1677 syncRendererState();
1678 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1679}
1680
Jamie Madill675fe712016-12-19 13:07:54 -05001681void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001682{
Jamie Madill675fe712016-12-19 13:07:54 -05001683 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001684}
1685
Jamie Madill675fe712016-12-19 13:07:54 -05001686void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001687{
Jamie Madill675fe712016-12-19 13:07:54 -05001688 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001689}
1690
Austin Kinross6ee1e782015-05-29 17:05:37 -07001691void Context::insertEventMarker(GLsizei length, const char *marker)
1692{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001693 ASSERT(mImplementation);
1694 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001695}
1696
1697void Context::pushGroupMarker(GLsizei length, const char *marker)
1698{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001699 ASSERT(mImplementation);
1700 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001701}
1702
1703void Context::popGroupMarker()
1704{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001705 ASSERT(mImplementation);
1706 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001707}
1708
Geoff Langd8605522016-04-13 10:19:12 -04001709void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1710{
1711 Program *programObject = getProgram(program);
1712 ASSERT(programObject);
1713
1714 programObject->bindUniformLocation(location, name);
1715}
1716
Sami Väisänena797e062016-05-12 15:23:40 +03001717void Context::setCoverageModulation(GLenum components)
1718{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001719 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001720}
1721
Sami Väisänene45e53b2016-05-25 10:36:04 +03001722void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1723{
1724 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1725}
1726
1727void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1728{
1729 GLfloat I[16];
1730 angle::Matrix<GLfloat>::setToIdentity(I);
1731
1732 mGLState.loadPathRenderingMatrix(matrixMode, I);
1733}
1734
1735void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1736{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001737 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001738 if (!pathObj)
1739 return;
1740
1741 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1742 syncRendererState();
1743
1744 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1745}
1746
1747void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1748{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001749 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001750 if (!pathObj)
1751 return;
1752
1753 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1754 syncRendererState();
1755
1756 mImplementation->stencilStrokePath(pathObj, reference, mask);
1757}
1758
1759void Context::coverFillPath(GLuint path, GLenum coverMode)
1760{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001761 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001762 if (!pathObj)
1763 return;
1764
1765 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1766 syncRendererState();
1767
1768 mImplementation->coverFillPath(pathObj, coverMode);
1769}
1770
1771void Context::coverStrokePath(GLuint path, GLenum coverMode)
1772{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001773 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001774 if (!pathObj)
1775 return;
1776
1777 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1778 syncRendererState();
1779
1780 mImplementation->coverStrokePath(pathObj, coverMode);
1781}
1782
1783void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1784{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001785 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001786 if (!pathObj)
1787 return;
1788
1789 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1790 syncRendererState();
1791
1792 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1793}
1794
1795void Context::stencilThenCoverStrokePath(GLuint path,
1796 GLint reference,
1797 GLuint mask,
1798 GLenum coverMode)
1799{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001800 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001801 if (!pathObj)
1802 return;
1803
1804 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1805 syncRendererState();
1806
1807 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1808}
1809
Sami Väisänend59ca052016-06-21 16:10:00 +03001810void Context::coverFillPathInstanced(GLsizei numPaths,
1811 GLenum pathNameType,
1812 const void *paths,
1813 GLuint pathBase,
1814 GLenum coverMode,
1815 GLenum transformType,
1816 const GLfloat *transformValues)
1817{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001818 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001819
1820 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1821 syncRendererState();
1822
1823 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1824}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001825
Sami Väisänend59ca052016-06-21 16:10:00 +03001826void Context::coverStrokePathInstanced(GLsizei numPaths,
1827 GLenum pathNameType,
1828 const void *paths,
1829 GLuint pathBase,
1830 GLenum coverMode,
1831 GLenum transformType,
1832 const GLfloat *transformValues)
1833{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001834 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001835
1836 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1837 syncRendererState();
1838
1839 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1840 transformValues);
1841}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001842
Sami Väisänend59ca052016-06-21 16:10:00 +03001843void Context::stencilFillPathInstanced(GLsizei numPaths,
1844 GLenum pathNameType,
1845 const void *paths,
1846 GLuint pathBase,
1847 GLenum fillMode,
1848 GLuint mask,
1849 GLenum transformType,
1850 const GLfloat *transformValues)
1851{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001852 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001853
1854 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1855 syncRendererState();
1856
1857 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1858 transformValues);
1859}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001860
Sami Väisänend59ca052016-06-21 16:10:00 +03001861void Context::stencilStrokePathInstanced(GLsizei numPaths,
1862 GLenum pathNameType,
1863 const void *paths,
1864 GLuint pathBase,
1865 GLint reference,
1866 GLuint mask,
1867 GLenum transformType,
1868 const GLfloat *transformValues)
1869{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001870 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001871
1872 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1873 syncRendererState();
1874
1875 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1876 transformValues);
1877}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001878
Sami Väisänend59ca052016-06-21 16:10:00 +03001879void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1880 GLenum pathNameType,
1881 const void *paths,
1882 GLuint pathBase,
1883 GLenum fillMode,
1884 GLuint mask,
1885 GLenum coverMode,
1886 GLenum transformType,
1887 const GLfloat *transformValues)
1888{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001889 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001890
1891 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1892 syncRendererState();
1893
1894 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1895 transformType, transformValues);
1896}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001897
Sami Väisänend59ca052016-06-21 16:10:00 +03001898void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1899 GLenum pathNameType,
1900 const void *paths,
1901 GLuint pathBase,
1902 GLint reference,
1903 GLuint mask,
1904 GLenum coverMode,
1905 GLenum transformType,
1906 const GLfloat *transformValues)
1907{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001908 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001909
1910 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1911 syncRendererState();
1912
1913 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1914 transformType, transformValues);
1915}
1916
Sami Väisänen46eaa942016-06-29 10:26:37 +03001917void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1918{
1919 auto *programObject = getProgram(program);
1920
1921 programObject->bindFragmentInputLocation(location, name);
1922}
1923
1924void Context::programPathFragmentInputGen(GLuint program,
1925 GLint location,
1926 GLenum genMode,
1927 GLint components,
1928 const GLfloat *coeffs)
1929{
1930 auto *programObject = getProgram(program);
1931
1932 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1933}
1934
Jamie Madill437fa652016-05-03 15:13:24 -04001935void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001936{
Geoff Langda5777c2014-07-11 09:52:58 -04001937 if (error.isError())
1938 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001939 GLenum code = error.getCode();
1940 mErrors.insert(code);
1941 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1942 {
1943 markContextLost();
1944 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001945
1946 if (!error.getMessage().empty())
1947 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001948 auto *debug = &mGLState.getDebug();
1949 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1950 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001951 }
Geoff Langda5777c2014-07-11 09:52:58 -04001952 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001953}
1954
1955// Get one of the recorded errors and clear its flag, if any.
1956// [OpenGL ES 2.0.24] section 2.5 page 13.
1957GLenum Context::getError()
1958{
Geoff Langda5777c2014-07-11 09:52:58 -04001959 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001960 {
Geoff Langda5777c2014-07-11 09:52:58 -04001961 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001962 }
Geoff Langda5777c2014-07-11 09:52:58 -04001963 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001964 {
Geoff Langda5777c2014-07-11 09:52:58 -04001965 GLenum error = *mErrors.begin();
1966 mErrors.erase(mErrors.begin());
1967 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001968 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001969}
1970
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001971// NOTE: this function should not assume that this context is current!
1972void Context::markContextLost()
1973{
1974 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001975 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001976 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001977 mContextLostForced = true;
1978 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001979 mContextLost = true;
1980}
1981
1982bool Context::isContextLost()
1983{
1984 return mContextLost;
1985}
1986
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001987GLenum Context::getResetStatus()
1988{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001989 // Even if the application doesn't want to know about resets, we want to know
1990 // as it will allow us to skip all the calls.
1991 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001992 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001993 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001994 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001995 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001996 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001997
1998 // EXT_robustness, section 2.6: If the reset notification behavior is
1999 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2000 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2001 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002002 }
2003
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002004 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2005 // status should be returned at least once, and GL_NO_ERROR should be returned
2006 // once the device has finished resetting.
2007 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002008 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002009 ASSERT(mResetStatus == GL_NO_ERROR);
2010 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002011
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002012 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002013 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002014 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002015 }
2016 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002017 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002018 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002019 // If markContextLost was used to mark the context lost then
2020 // assume that is not recoverable, and continue to report the
2021 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002022 mResetStatus = mImplementation->getResetStatus();
2023 }
Jamie Madill893ab082014-05-16 16:56:10 -04002024
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002025 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002026}
2027
2028bool Context::isResetNotificationEnabled()
2029{
2030 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2031}
2032
Corentin Walleze3b10e82015-05-20 11:06:25 -04002033const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002034{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002035 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002036}
2037
2038EGLenum Context::getClientType() const
2039{
2040 return mClientType;
2041}
2042
2043EGLenum Context::getRenderBuffer() const
2044{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002045 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2046 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002047 {
2048 return EGL_NONE;
2049 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002050
2051 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2052 ASSERT(backAttachment != nullptr);
2053 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002054}
2055
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002056VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002057{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002058 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002059 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2060 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002061 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002062 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2063
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002064 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002065 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002066
2067 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002068}
2069
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002070TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002071{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002072 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002073 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2074 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002075 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002076 transformFeedback =
2077 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002078 transformFeedback->addRef();
2079 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002080 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002081
2082 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002083}
2084
2085bool Context::isVertexArrayGenerated(GLuint vertexArray)
2086{
Geoff Langf41a7152016-09-19 15:11:17 -04002087 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002088 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2089}
2090
2091bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2092{
Geoff Langf41a7152016-09-19 15:11:17 -04002093 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002094 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2095}
2096
Shannon Woods53a94a82014-06-24 15:20:36 -04002097void Context::detachTexture(GLuint texture)
2098{
2099 // Simple pass-through to State's detachTexture method, as textures do not require
2100 // allocation map management either here or in the resource manager at detach time.
2101 // Zero textures are held by the Context, and we don't attempt to request them from
2102 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002103 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002104}
2105
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002106void Context::detachBuffer(GLuint buffer)
2107{
Yuly Novikov5807a532015-12-03 13:01:22 -05002108 // Simple pass-through to State's detachBuffer method, since
2109 // only buffer attachments to container objects that are bound to the current context
2110 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002111
Yuly Novikov5807a532015-12-03 13:01:22 -05002112 // [OpenGL ES 3.2] section 5.1.2 page 45:
2113 // Attachments to unbound container objects, such as
2114 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2115 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002116 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002117}
2118
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002119void Context::detachFramebuffer(GLuint framebuffer)
2120{
Shannon Woods53a94a82014-06-24 15:20:36 -04002121 // Framebuffer detachment is handled by Context, because 0 is a valid
2122 // Framebuffer object, and a pointer to it must be passed from Context
2123 // to State at binding time.
2124
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002125 // [OpenGL ES 2.0.24] section 4.4 page 107:
2126 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2127 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2128
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002129 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002130 {
2131 bindReadFramebuffer(0);
2132 }
2133
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002134 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002135 {
2136 bindDrawFramebuffer(0);
2137 }
2138}
2139
2140void Context::detachRenderbuffer(GLuint renderbuffer)
2141{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002142 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002143}
2144
Jamie Madill57a89722013-07-02 11:57:03 -04002145void Context::detachVertexArray(GLuint vertexArray)
2146{
Jamie Madill77a72f62015-04-14 11:18:32 -04002147 // Vertex array detachment is handled by Context, because 0 is a valid
2148 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002149 // binding time.
2150
Jamie Madill57a89722013-07-02 11:57:03 -04002151 // [OpenGL ES 3.0.2] section 2.10 page 43:
2152 // If a vertex array object that is currently bound is deleted, the binding
2153 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002154 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002155 {
2156 bindVertexArray(0);
2157 }
2158}
2159
Geoff Langc8058452014-02-03 12:04:11 -05002160void Context::detachTransformFeedback(GLuint transformFeedback)
2161{
Corentin Walleza2257da2016-04-19 16:43:12 -04002162 // Transform feedback detachment is handled by Context, because 0 is a valid
2163 // transform feedback, and a pointer to it must be passed from Context to State at
2164 // binding time.
2165
2166 // The OpenGL specification doesn't mention what should happen when the currently bound
2167 // transform feedback object is deleted. Since it is a container object, we treat it like
2168 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002169 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002170 {
2171 bindTransformFeedback(0);
2172 }
Geoff Langc8058452014-02-03 12:04:11 -05002173}
2174
Jamie Madilldc356042013-07-19 16:36:57 -04002175void Context::detachSampler(GLuint sampler)
2176{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002177 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002178}
2179
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002180void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2181{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002182 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002183}
2184
Jamie Madille29d1672013-07-19 16:36:57 -04002185void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2186{
Geoff Langc1984ed2016-10-07 12:41:00 -04002187 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002188 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002189 SetSamplerParameteri(samplerObject, pname, param);
2190}
Jamie Madille29d1672013-07-19 16:36:57 -04002191
Geoff Langc1984ed2016-10-07 12:41:00 -04002192void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2193{
2194 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002195 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002196 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002197}
2198
2199void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2200{
Geoff Langc1984ed2016-10-07 12:41:00 -04002201 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002202 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002203 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002204}
2205
Geoff Langc1984ed2016-10-07 12:41:00 -04002206void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002207{
Geoff Langc1984ed2016-10-07 12:41:00 -04002208 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002209 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002210 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002211}
2212
Geoff Langc1984ed2016-10-07 12:41:00 -04002213void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002214{
Geoff Langc1984ed2016-10-07 12:41:00 -04002215 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002216 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002217 QuerySamplerParameteriv(samplerObject, pname, params);
2218}
Jamie Madill9675b802013-07-19 16:36:59 -04002219
Geoff Langc1984ed2016-10-07 12:41:00 -04002220void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2221{
2222 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002223 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002224 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002225}
2226
Olli Etuahof0fee072016-03-30 15:11:58 +03002227void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2228{
2229 gl::Program *programObject = getProgram(program);
2230 ASSERT(programObject != nullptr);
2231
2232 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2233 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2234}
2235
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002236void Context::initRendererString()
2237{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002238 std::ostringstream rendererString;
2239 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002240 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002241 rendererString << ")";
2242
Geoff Langcec35902014-04-16 10:52:36 -04002243 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002244}
2245
Geoff Langc339c4e2016-11-29 10:37:36 -05002246void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002247{
Geoff Langc339c4e2016-11-29 10:37:36 -05002248 const Version &clientVersion = getClientVersion();
2249
2250 std::ostringstream versionString;
2251 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2252 << ANGLE_VERSION_STRING << ")";
2253 mVersionString = MakeStaticString(versionString.str());
2254
2255 std::ostringstream shadingLanguageVersionString;
2256 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2257 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2258 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2259 << ")";
2260 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002261}
2262
Geoff Langcec35902014-04-16 10:52:36 -04002263void Context::initExtensionStrings()
2264{
Geoff Langc339c4e2016-11-29 10:37:36 -05002265 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2266 std::ostringstream combinedStringStream;
2267 std::copy(strings.begin(), strings.end(),
2268 std::ostream_iterator<const char *>(combinedStringStream, " "));
2269 return MakeStaticString(combinedStringStream.str());
2270 };
2271
2272 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002273 for (const auto &extensionString : mExtensions.getStrings())
2274 {
2275 mExtensionStrings.push_back(MakeStaticString(extensionString));
2276 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002277 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002278
Bryan Bernhart58806562017-01-05 13:09:31 -08002279 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2280
Geoff Langc339c4e2016-11-29 10:37:36 -05002281 mRequestableExtensionStrings.clear();
2282 for (const auto &extensionInfo : GetExtensionInfoMap())
2283 {
2284 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002285 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2286 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002287 {
2288 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2289 }
2290 }
2291 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002292}
2293
Geoff Langc339c4e2016-11-29 10:37:36 -05002294const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002295{
Geoff Langc339c4e2016-11-29 10:37:36 -05002296 switch (name)
2297 {
2298 case GL_VENDOR:
2299 return reinterpret_cast<const GLubyte *>("Google Inc.");
2300
2301 case GL_RENDERER:
2302 return reinterpret_cast<const GLubyte *>(mRendererString);
2303
2304 case GL_VERSION:
2305 return reinterpret_cast<const GLubyte *>(mVersionString);
2306
2307 case GL_SHADING_LANGUAGE_VERSION:
2308 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2309
2310 case GL_EXTENSIONS:
2311 return reinterpret_cast<const GLubyte *>(mExtensionString);
2312
2313 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2314 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2315
2316 default:
2317 UNREACHABLE();
2318 return nullptr;
2319 }
Geoff Langcec35902014-04-16 10:52:36 -04002320}
2321
Geoff Langc339c4e2016-11-29 10:37:36 -05002322const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002323{
Geoff Langc339c4e2016-11-29 10:37:36 -05002324 switch (name)
2325 {
2326 case GL_EXTENSIONS:
2327 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2328
2329 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2330 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2331
2332 default:
2333 UNREACHABLE();
2334 return nullptr;
2335 }
Geoff Langcec35902014-04-16 10:52:36 -04002336}
2337
2338size_t Context::getExtensionStringCount() const
2339{
2340 return mExtensionStrings.size();
2341}
2342
Geoff Langc339c4e2016-11-29 10:37:36 -05002343void Context::requestExtension(const char *name)
2344{
2345 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2346 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2347 const auto &extension = extensionInfos.at(name);
2348 ASSERT(extension.Requestable);
2349
2350 if (mExtensions.*(extension.ExtensionsMember))
2351 {
2352 // Extension already enabled
2353 return;
2354 }
2355
2356 mExtensions.*(extension.ExtensionsMember) = true;
2357 updateCaps();
2358 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002359
2360 // Re-create the compiler with the requested extensions enabled.
2361 SafeDelete(mCompiler);
2362 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002363}
2364
2365size_t Context::getRequestableExtensionStringCount() const
2366{
2367 return mRequestableExtensionStrings.size();
2368}
2369
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002370void Context::beginTransformFeedback(GLenum primitiveMode)
2371{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002372 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002373 ASSERT(transformFeedback != nullptr);
2374 ASSERT(!transformFeedback->isPaused());
2375
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002376 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002377}
2378
2379bool Context::hasActiveTransformFeedback(GLuint program) const
2380{
2381 for (auto pair : mTransformFeedbackMap)
2382 {
2383 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2384 {
2385 return true;
2386 }
2387 }
2388 return false;
2389}
2390
Corentin Wallezc295e512017-01-27 17:47:50 -05002391void Context::initCaps(bool webGLContext, const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002392{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002393 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002394
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002395 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002396
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002397 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002398
Geoff Langeb66a6e2016-10-31 13:06:12 -04002399 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002400 {
2401 // Disable ES3+ extensions
2402 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002403 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002404 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002405 }
2406
Geoff Langeb66a6e2016-10-31 13:06:12 -04002407 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002408 {
2409 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2410 //mExtensions.sRGB = false;
2411 }
2412
Jamie Madill00ed7a12016-05-19 13:13:38 -04002413 // Some extensions are always available because they are implemented in the GL layer.
2414 mExtensions.bindUniformLocation = true;
2415 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002416 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002417 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002418
2419 // Enable the no error extension if the context was created with the flag.
2420 mExtensions.noError = mSkipValidation;
2421
Corentin Wallezccab69d2017-01-27 16:57:15 -05002422 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002423 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002424
Geoff Lang70d0f492015-12-10 17:45:46 -05002425 // Explicitly enable GL_KHR_debug
2426 mExtensions.debug = true;
2427 mExtensions.maxDebugMessageLength = 1024;
2428 mExtensions.maxDebugLoggedMessages = 1024;
2429 mExtensions.maxDebugGroupStackDepth = 1024;
2430 mExtensions.maxLabelLength = 1024;
2431
Geoff Langff5b2d52016-09-07 11:32:23 -04002432 // Explicitly enable GL_ANGLE_robust_client_memory
2433 mExtensions.robustClientMemory = true;
2434
Geoff Lang301d1612014-07-09 10:34:37 -04002435 // Apply implementation limits
2436 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002437 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2438 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2439
2440 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002441
Geoff Langc287ea62016-09-16 14:46:51 -04002442 // WebGL compatibility
2443 mExtensions.webglCompatibility = webGLContext;
2444 for (const auto &extensionInfo : GetExtensionInfoMap())
2445 {
2446 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002447 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002448 {
2449 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2450 }
2451 }
2452
2453 // Generate texture caps
2454 updateCaps();
2455}
2456
2457void Context::updateCaps()
2458{
Geoff Lang900013c2014-07-07 11:32:19 -04002459 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002460 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002461
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002462 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002463 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2464 {
2465 GLenum format = i->first;
2466 TextureCaps formatCaps = i->second;
2467
Geoff Lang5d601382014-07-22 15:14:06 -04002468 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002469
Geoff Lang0d8b7242015-09-09 14:56:53 -04002470 // Update the format caps based on the client version and extensions.
2471 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2472 // ES3.
2473 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002474 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002475 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002476 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002477 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002478 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002479
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002480 // OpenGL ES does not support multisampling with non-rendererable formats
2481 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2482 if (!formatInfo.renderSupport ||
2483 (getClientVersion() < ES_3_1 &&
2484 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002485 {
Geoff Langd87878e2014-09-19 15:42:59 -04002486 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002487 }
Geoff Langd87878e2014-09-19 15:42:59 -04002488
2489 if (formatCaps.texturable && formatInfo.compressed)
2490 {
2491 mCaps.compressedTextureFormats.push_back(format);
2492 }
2493
2494 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002495 }
2496}
2497
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002498void Context::initWorkarounds()
2499{
2500 // Lose the context upon out of memory error if the application is
2501 // expecting to watch for those events.
2502 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2503}
2504
Jamie Madill1b94d432015-08-07 13:23:23 -04002505void Context::syncRendererState()
2506{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002507 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2508 mImplementation->syncState(mGLState, dirtyBits);
2509 mGLState.clearDirtyBits();
2510 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002511}
2512
Jamie Madillad9f24e2016-02-12 09:27:24 -05002513void Context::syncRendererState(const State::DirtyBits &bitMask,
2514 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002515{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002516 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2517 mImplementation->syncState(mGLState, dirtyBits);
2518 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002519
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002520 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002521}
Jamie Madillc29968b2016-01-20 11:17:23 -05002522
2523void Context::blitFramebuffer(GLint srcX0,
2524 GLint srcY0,
2525 GLint srcX1,
2526 GLint srcY1,
2527 GLint dstX0,
2528 GLint dstY0,
2529 GLint dstX1,
2530 GLint dstY1,
2531 GLbitfield mask,
2532 GLenum filter)
2533{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002534 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002535 ASSERT(drawFramebuffer);
2536
2537 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2538 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2539
Jamie Madillad9f24e2016-02-12 09:27:24 -05002540 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002541
Jamie Madill8415b5f2016-04-26 13:41:39 -04002542 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002543}
Jamie Madillc29968b2016-01-20 11:17:23 -05002544
2545void Context::clear(GLbitfield mask)
2546{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002547 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002548 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002549}
2550
2551void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2552{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002553 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002554 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2555 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002556}
2557
2558void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2559{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002560 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002561 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2562 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002563}
2564
2565void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2566{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002567 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002568 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2569 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002570}
2571
2572void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2573{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002574 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002575 ASSERT(framebufferObject);
2576
2577 // If a buffer is not present, the clear has no effect
2578 if (framebufferObject->getDepthbuffer() == nullptr &&
2579 framebufferObject->getStencilbuffer() == nullptr)
2580 {
2581 return;
2582 }
2583
Jamie Madillad9f24e2016-02-12 09:27:24 -05002584 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002585 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2586 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002587}
2588
2589void Context::readPixels(GLint x,
2590 GLint y,
2591 GLsizei width,
2592 GLsizei height,
2593 GLenum format,
2594 GLenum type,
2595 GLvoid *pixels)
2596{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002597 if (width == 0 || height == 0)
2598 {
2599 return;
2600 }
2601
Jamie Madillad9f24e2016-02-12 09:27:24 -05002602 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002603
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002604 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002605 ASSERT(framebufferObject);
2606
2607 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002608 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002609}
2610
2611void Context::copyTexImage2D(GLenum target,
2612 GLint level,
2613 GLenum internalformat,
2614 GLint x,
2615 GLint y,
2616 GLsizei width,
2617 GLsizei height,
2618 GLint border)
2619{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002620 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002621 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002622
Jamie Madillc29968b2016-01-20 11:17:23 -05002623 Rectangle sourceArea(x, y, width, height);
2624
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002625 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002626 Texture *texture =
2627 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002628 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002629}
2630
2631void Context::copyTexSubImage2D(GLenum target,
2632 GLint level,
2633 GLint xoffset,
2634 GLint yoffset,
2635 GLint x,
2636 GLint y,
2637 GLsizei width,
2638 GLsizei height)
2639{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002640 if (width == 0 || height == 0)
2641 {
2642 return;
2643 }
2644
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002645 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002646 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002647
Jamie Madillc29968b2016-01-20 11:17:23 -05002648 Offset destOffset(xoffset, yoffset, 0);
2649 Rectangle sourceArea(x, y, width, height);
2650
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002651 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002652 Texture *texture =
2653 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002654 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002655}
2656
2657void Context::copyTexSubImage3D(GLenum target,
2658 GLint level,
2659 GLint xoffset,
2660 GLint yoffset,
2661 GLint zoffset,
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, zoffset);
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 = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002680 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002681}
2682
2683void Context::framebufferTexture2D(GLenum target,
2684 GLenum attachment,
2685 GLenum textarget,
2686 GLuint texture,
2687 GLint level)
2688{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002689 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002690 ASSERT(framebuffer);
2691
2692 if (texture != 0)
2693 {
2694 Texture *textureObj = getTexture(texture);
2695
2696 ImageIndex index = ImageIndex::MakeInvalid();
2697
2698 if (textarget == GL_TEXTURE_2D)
2699 {
2700 index = ImageIndex::Make2D(level);
2701 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002702 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2703 {
2704 ASSERT(level == 0);
2705 index = ImageIndex::Make2DMultisample();
2706 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002707 else
2708 {
2709 ASSERT(IsCubeMapTextureTarget(textarget));
2710 index = ImageIndex::MakeCube(textarget, level);
2711 }
2712
2713 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2714 }
2715 else
2716 {
2717 framebuffer->resetAttachment(attachment);
2718 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002719
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002720 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002721}
2722
2723void Context::framebufferRenderbuffer(GLenum target,
2724 GLenum attachment,
2725 GLenum renderbuffertarget,
2726 GLuint renderbuffer)
2727{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002728 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002729 ASSERT(framebuffer);
2730
2731 if (renderbuffer != 0)
2732 {
2733 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2734 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2735 renderbufferObject);
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::framebufferTextureLayer(GLenum target,
2746 GLenum attachment,
2747 GLuint texture,
2748 GLint level,
2749 GLint layer)
2750{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002751 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002752 ASSERT(framebuffer);
2753
2754 if (texture != 0)
2755 {
2756 Texture *textureObject = getTexture(texture);
2757
2758 ImageIndex index = ImageIndex::MakeInvalid();
2759
2760 if (textureObject->getTarget() == GL_TEXTURE_3D)
2761 {
2762 index = ImageIndex::Make3D(level, layer);
2763 }
2764 else
2765 {
2766 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2767 index = ImageIndex::Make2DArray(level, layer);
2768 }
2769
2770 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2771 }
2772 else
2773 {
2774 framebuffer->resetAttachment(attachment);
2775 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002776
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002777 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002778}
2779
2780void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2781{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002782 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002783 ASSERT(framebuffer);
2784 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002785 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002786}
2787
2788void Context::readBuffer(GLenum mode)
2789{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002790 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002791 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002792 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002793}
2794
2795void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2796{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002797 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002798 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002799
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002800 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002801 ASSERT(framebuffer);
2802
2803 // The specification isn't clear what should be done when the framebuffer isn't complete.
2804 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002805 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002806}
2807
2808void Context::invalidateFramebuffer(GLenum target,
2809 GLsizei numAttachments,
2810 const GLenum *attachments)
2811{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002812 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002813 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002814
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002815 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002816 ASSERT(framebuffer);
2817
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002818 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002819 {
Jamie Madill437fa652016-05-03 15:13:24 -04002820 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002821 }
Jamie Madill437fa652016-05-03 15:13:24 -04002822
2823 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002824}
2825
2826void Context::invalidateSubFramebuffer(GLenum target,
2827 GLsizei numAttachments,
2828 const GLenum *attachments,
2829 GLint x,
2830 GLint y,
2831 GLsizei width,
2832 GLsizei height)
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 Rectangle area(x, y, width, height);
2846 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002847}
2848
Jamie Madill73a84962016-02-12 09:27:23 -05002849void Context::texImage2D(GLenum target,
2850 GLint level,
2851 GLint internalformat,
2852 GLsizei width,
2853 GLsizei height,
2854 GLint border,
2855 GLenum format,
2856 GLenum type,
2857 const GLvoid *pixels)
2858{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002859 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002860
2861 Extents size(width, height, 1);
2862 Texture *texture =
2863 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002864 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002865 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002866}
2867
2868void Context::texImage3D(GLenum target,
2869 GLint level,
2870 GLint internalformat,
2871 GLsizei width,
2872 GLsizei height,
2873 GLsizei depth,
2874 GLint border,
2875 GLenum format,
2876 GLenum type,
2877 const GLvoid *pixels)
2878{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002879 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002880
2881 Extents size(width, height, depth);
2882 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002883 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002884 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002885}
2886
2887void Context::texSubImage2D(GLenum target,
2888 GLint level,
2889 GLint xoffset,
2890 GLint yoffset,
2891 GLsizei width,
2892 GLsizei height,
2893 GLenum format,
2894 GLenum type,
2895 const GLvoid *pixels)
2896{
2897 // Zero sized uploads are valid but no-ops
2898 if (width == 0 || height == 0)
2899 {
2900 return;
2901 }
2902
Jamie Madillad9f24e2016-02-12 09:27:24 -05002903 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002904
2905 Box area(xoffset, yoffset, 0, width, height, 1);
2906 Texture *texture =
2907 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002908 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002909 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002910}
2911
2912void Context::texSubImage3D(GLenum target,
2913 GLint level,
2914 GLint xoffset,
2915 GLint yoffset,
2916 GLint zoffset,
2917 GLsizei width,
2918 GLsizei height,
2919 GLsizei depth,
2920 GLenum format,
2921 GLenum type,
2922 const GLvoid *pixels)
2923{
2924 // Zero sized uploads are valid but no-ops
2925 if (width == 0 || height == 0 || depth == 0)
2926 {
2927 return;
2928 }
2929
Jamie Madillad9f24e2016-02-12 09:27:24 -05002930 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002931
2932 Box area(xoffset, yoffset, zoffset, width, height, depth);
2933 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002934 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002935 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002936}
2937
2938void Context::compressedTexImage2D(GLenum target,
2939 GLint level,
2940 GLenum internalformat,
2941 GLsizei width,
2942 GLsizei height,
2943 GLint border,
2944 GLsizei imageSize,
2945 const GLvoid *data)
2946{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002947 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002948
2949 Extents size(width, height, 1);
2950 Texture *texture =
2951 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002952 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2953 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002954 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002955}
2956
2957void Context::compressedTexImage3D(GLenum target,
2958 GLint level,
2959 GLenum internalformat,
2960 GLsizei width,
2961 GLsizei height,
2962 GLsizei depth,
2963 GLint border,
2964 GLsizei imageSize,
2965 const GLvoid *data)
2966{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002967 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002968
2969 Extents size(width, height, depth);
2970 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002971 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2972 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002973 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002974}
2975
2976void Context::compressedTexSubImage2D(GLenum target,
2977 GLint level,
2978 GLint xoffset,
2979 GLint yoffset,
2980 GLsizei width,
2981 GLsizei height,
2982 GLenum format,
2983 GLsizei imageSize,
2984 const GLvoid *data)
2985{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002986 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002987
2988 Box area(xoffset, yoffset, 0, width, height, 1);
2989 Texture *texture =
2990 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002991 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2992 format, imageSize,
2993 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002994}
2995
2996void Context::compressedTexSubImage3D(GLenum target,
2997 GLint level,
2998 GLint xoffset,
2999 GLint yoffset,
3000 GLint zoffset,
3001 GLsizei width,
3002 GLsizei height,
3003 GLsizei depth,
3004 GLenum format,
3005 GLsizei imageSize,
3006 const GLvoid *data)
3007{
3008 // Zero sized uploads are valid but no-ops
3009 if (width == 0 || height == 0)
3010 {
3011 return;
3012 }
3013
Jamie Madillad9f24e2016-02-12 09:27:24 -05003014 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003015
3016 Box area(xoffset, yoffset, zoffset, width, height, depth);
3017 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003018 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3019 format, imageSize,
3020 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003021}
3022
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003023void Context::generateMipmap(GLenum target)
3024{
3025 Texture *texture = getTargetTexture(target);
3026 handleError(texture->generateMipmap());
3027}
3028
Geoff Lang97073d12016-04-20 10:42:34 -07003029void Context::copyTextureCHROMIUM(GLuint sourceId,
3030 GLuint destId,
3031 GLint internalFormat,
3032 GLenum destType,
3033 GLboolean unpackFlipY,
3034 GLboolean unpackPremultiplyAlpha,
3035 GLboolean unpackUnmultiplyAlpha)
3036{
3037 syncStateForTexImage();
3038
3039 gl::Texture *sourceTexture = getTexture(sourceId);
3040 gl::Texture *destTexture = getTexture(destId);
3041 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3042 unpackPremultiplyAlpha == GL_TRUE,
3043 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3044}
3045
3046void Context::copySubTextureCHROMIUM(GLuint sourceId,
3047 GLuint destId,
3048 GLint xoffset,
3049 GLint yoffset,
3050 GLint x,
3051 GLint y,
3052 GLsizei width,
3053 GLsizei height,
3054 GLboolean unpackFlipY,
3055 GLboolean unpackPremultiplyAlpha,
3056 GLboolean unpackUnmultiplyAlpha)
3057{
3058 // Zero sized copies are valid but no-ops
3059 if (width == 0 || height == 0)
3060 {
3061 return;
3062 }
3063
3064 syncStateForTexImage();
3065
3066 gl::Texture *sourceTexture = getTexture(sourceId);
3067 gl::Texture *destTexture = getTexture(destId);
3068 Offset offset(xoffset, yoffset, 0);
3069 Rectangle area(x, y, width, height);
3070 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3071 unpackPremultiplyAlpha == GL_TRUE,
3072 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3073}
3074
Geoff Lang47110bf2016-04-20 11:13:22 -07003075void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3076{
3077 syncStateForTexImage();
3078
3079 gl::Texture *sourceTexture = getTexture(sourceId);
3080 gl::Texture *destTexture = getTexture(destId);
3081 handleError(destTexture->copyCompressedTexture(sourceTexture));
3082}
3083
Geoff Lang496c02d2016-10-20 11:38:11 -07003084void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003085{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003086 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003087 ASSERT(buffer);
3088
Geoff Lang496c02d2016-10-20 11:38:11 -07003089 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003090}
3091
3092GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3093{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003094 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003095 ASSERT(buffer);
3096
3097 Error error = buffer->map(access);
3098 if (error.isError())
3099 {
Jamie Madill437fa652016-05-03 15:13:24 -04003100 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003101 return nullptr;
3102 }
3103
3104 return buffer->getMapPointer();
3105}
3106
3107GLboolean Context::unmapBuffer(GLenum target)
3108{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003109 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003110 ASSERT(buffer);
3111
3112 GLboolean result;
3113 Error error = buffer->unmap(&result);
3114 if (error.isError())
3115 {
Jamie Madill437fa652016-05-03 15:13:24 -04003116 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003117 return GL_FALSE;
3118 }
3119
3120 return result;
3121}
3122
3123GLvoid *Context::mapBufferRange(GLenum target,
3124 GLintptr offset,
3125 GLsizeiptr length,
3126 GLbitfield access)
3127{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003128 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003129 ASSERT(buffer);
3130
3131 Error error = buffer->mapRange(offset, length, access);
3132 if (error.isError())
3133 {
Jamie Madill437fa652016-05-03 15:13:24 -04003134 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003135 return nullptr;
3136 }
3137
3138 return buffer->getMapPointer();
3139}
3140
3141void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3142{
3143 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3144}
3145
Jamie Madillad9f24e2016-02-12 09:27:24 -05003146void Context::syncStateForReadPixels()
3147{
3148 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3149}
3150
3151void Context::syncStateForTexImage()
3152{
3153 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3154}
3155
3156void Context::syncStateForClear()
3157{
3158 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3159}
3160
3161void Context::syncStateForBlit()
3162{
3163 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3164}
3165
Jamie Madillc20ab272016-06-09 07:20:46 -07003166void Context::activeTexture(GLenum texture)
3167{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003168 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003169}
3170
3171void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3172{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003173 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003174}
3175
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003176void Context::blendEquation(GLenum mode)
3177{
3178 mGLState.setBlendEquation(mode, mode);
3179}
3180
Jamie Madillc20ab272016-06-09 07:20:46 -07003181void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3182{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003183 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003184}
3185
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003186void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3187{
3188 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3189}
3190
Jamie Madillc20ab272016-06-09 07:20:46 -07003191void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3192{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003193 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003194}
3195
3196void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3197{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003198 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003199}
3200
3201void Context::clearDepthf(GLclampf depth)
3202{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003203 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003204}
3205
3206void Context::clearStencil(GLint s)
3207{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003208 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003209}
3210
3211void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3212{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003213 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003214}
3215
3216void Context::cullFace(GLenum mode)
3217{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003218 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003219}
3220
3221void Context::depthFunc(GLenum func)
3222{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003223 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003224}
3225
3226void Context::depthMask(GLboolean flag)
3227{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003228 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003229}
3230
3231void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3232{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003233 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003234}
3235
3236void Context::disable(GLenum cap)
3237{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003238 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003239}
3240
3241void Context::disableVertexAttribArray(GLuint index)
3242{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003243 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003244}
3245
3246void Context::enable(GLenum cap)
3247{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003248 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003249}
3250
3251void Context::enableVertexAttribArray(GLuint index)
3252{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003253 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003254}
3255
3256void Context::frontFace(GLenum mode)
3257{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003258 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003259}
3260
3261void Context::hint(GLenum target, GLenum mode)
3262{
3263 switch (target)
3264 {
3265 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003266 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003267 break;
3268
3269 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003270 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003271 break;
3272
3273 default:
3274 UNREACHABLE();
3275 return;
3276 }
3277}
3278
3279void Context::lineWidth(GLfloat width)
3280{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003281 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003282}
3283
3284void Context::pixelStorei(GLenum pname, GLint param)
3285{
3286 switch (pname)
3287 {
3288 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003289 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003290 break;
3291
3292 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003293 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003294 break;
3295
3296 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003297 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003298 break;
3299
3300 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003301 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003302 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003303 break;
3304
3305 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003306 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003307 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003308 break;
3309
3310 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003311 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003312 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003313 break;
3314
3315 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003316 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003317 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003318 break;
3319
3320 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003321 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003322 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003323 break;
3324
3325 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003326 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003327 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003328 break;
3329
3330 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003331 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003332 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003333 break;
3334
3335 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003336 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003337 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003338 break;
3339
3340 default:
3341 UNREACHABLE();
3342 return;
3343 }
3344}
3345
3346void Context::polygonOffset(GLfloat factor, GLfloat units)
3347{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003348 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003349}
3350
3351void Context::sampleCoverage(GLclampf value, GLboolean invert)
3352{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003353 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003354}
3355
3356void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3357{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003358 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003359}
3360
3361void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3362{
3363 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3364 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003365 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003366 }
3367
3368 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3369 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003370 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003371 }
3372}
3373
3374void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3375{
3376 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3377 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003378 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003379 }
3380
3381 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3382 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003383 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003384 }
3385}
3386
3387void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3388{
3389 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3390 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003391 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003392 }
3393
3394 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3395 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003396 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003397 }
3398}
3399
3400void Context::vertexAttrib1f(GLuint index, GLfloat x)
3401{
3402 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003403 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003404}
3405
3406void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3407{
3408 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003409 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003410}
3411
3412void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3413{
3414 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003415 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003416}
3417
3418void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3419{
3420 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003421 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003422}
3423
3424void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3425{
3426 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003427 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003428}
3429
3430void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3431{
3432 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003433 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003434}
3435
3436void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3437{
3438 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003439 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003440}
3441
3442void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3443{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003444 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003445}
3446
3447void Context::vertexAttribPointer(GLuint index,
3448 GLint size,
3449 GLenum type,
3450 GLboolean normalized,
3451 GLsizei stride,
3452 const GLvoid *ptr)
3453{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003454 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3455 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003456}
3457
3458void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3459{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003460 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003461}
3462
3463void Context::vertexAttribIPointer(GLuint index,
3464 GLint size,
3465 GLenum type,
3466 GLsizei stride,
3467 const GLvoid *pointer)
3468{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003469 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3470 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003471}
3472
3473void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3474{
3475 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003476 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003477}
3478
3479void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3480{
3481 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003482 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003483}
3484
3485void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3486{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003487 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003488}
3489
3490void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3491{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003492 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003493}
3494
3495void Context::debugMessageControl(GLenum source,
3496 GLenum type,
3497 GLenum severity,
3498 GLsizei count,
3499 const GLuint *ids,
3500 GLboolean enabled)
3501{
3502 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003503 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3504 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003505}
3506
3507void Context::debugMessageInsert(GLenum source,
3508 GLenum type,
3509 GLuint id,
3510 GLenum severity,
3511 GLsizei length,
3512 const GLchar *buf)
3513{
3514 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003515 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003516}
3517
3518void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3519{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
3523GLuint Context::getDebugMessageLog(GLuint count,
3524 GLsizei bufSize,
3525 GLenum *sources,
3526 GLenum *types,
3527 GLuint *ids,
3528 GLenum *severities,
3529 GLsizei *lengths,
3530 GLchar *messageLog)
3531{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003532 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3533 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003534}
3535
3536void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3537{
3538 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003539 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003540}
3541
3542void Context::popDebugGroup()
3543{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003545}
3546
Jamie Madill29639852016-09-02 15:00:09 -04003547void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3548{
3549 Buffer *buffer = mGLState.getTargetBuffer(target);
3550 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003551 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003552}
3553
3554void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3555{
3556 if (data == nullptr)
3557 {
3558 return;
3559 }
3560
3561 Buffer *buffer = mGLState.getTargetBuffer(target);
3562 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003563 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003564}
3565
Jamie Madillef300b12016-10-07 15:12:09 -04003566void Context::attachShader(GLuint program, GLuint shader)
3567{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003568 auto programObject = mState.mShaderPrograms->getProgram(program);
3569 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003570 ASSERT(programObject && shaderObject);
3571 programObject->attachShader(shaderObject);
3572}
3573
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003574const Workarounds &Context::getWorkarounds() const
3575{
3576 return mWorkarounds;
3577}
3578
Jamie Madillb0817d12016-11-01 15:48:31 -04003579void Context::copyBufferSubData(GLenum readTarget,
3580 GLenum writeTarget,
3581 GLintptr readOffset,
3582 GLintptr writeOffset,
3583 GLsizeiptr size)
3584{
3585 // if size is zero, the copy is a successful no-op
3586 if (size == 0)
3587 {
3588 return;
3589 }
3590
3591 // TODO(jmadill): cache these.
3592 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3593 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3594
3595 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3596}
3597
Jamie Madill01a80ee2016-11-07 12:06:18 -05003598void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3599{
3600 Program *programObject = getProgram(program);
3601 // TODO(jmadill): Re-use this from the validation if possible.
3602 ASSERT(programObject);
3603 programObject->bindAttributeLocation(index, name);
3604}
3605
3606void Context::bindBuffer(GLenum target, GLuint buffer)
3607{
3608 switch (target)
3609 {
3610 case GL_ARRAY_BUFFER:
3611 bindArrayBuffer(buffer);
3612 break;
3613 case GL_ELEMENT_ARRAY_BUFFER:
3614 bindElementArrayBuffer(buffer);
3615 break;
3616 case GL_COPY_READ_BUFFER:
3617 bindCopyReadBuffer(buffer);
3618 break;
3619 case GL_COPY_WRITE_BUFFER:
3620 bindCopyWriteBuffer(buffer);
3621 break;
3622 case GL_PIXEL_PACK_BUFFER:
3623 bindPixelPackBuffer(buffer);
3624 break;
3625 case GL_PIXEL_UNPACK_BUFFER:
3626 bindPixelUnpackBuffer(buffer);
3627 break;
3628 case GL_UNIFORM_BUFFER:
3629 bindGenericUniformBuffer(buffer);
3630 break;
3631 case GL_TRANSFORM_FEEDBACK_BUFFER:
3632 bindGenericTransformFeedbackBuffer(buffer);
3633 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003634 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003635 if (buffer != 0)
3636 {
3637 // Binding buffers to this binding point is not implemented yet.
3638 UNIMPLEMENTED();
3639 }
Geoff Lang3b573612016-10-31 14:08:10 -04003640 break;
3641 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003642 if (buffer != 0)
3643 {
3644 // Binding buffers to this binding point is not implemented yet.
3645 UNIMPLEMENTED();
3646 }
Geoff Lang3b573612016-10-31 14:08:10 -04003647 break;
3648 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003649 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003650 break;
3651 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003652 if (buffer != 0)
3653 {
3654 // Binding buffers to this binding point is not implemented yet.
3655 UNIMPLEMENTED();
3656 }
Geoff Lang3b573612016-10-31 14:08:10 -04003657 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003658
3659 default:
3660 UNREACHABLE();
3661 break;
3662 }
3663}
3664
3665void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3666{
3667 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3668 {
3669 bindReadFramebuffer(framebuffer);
3670 }
3671
3672 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3673 {
3674 bindDrawFramebuffer(framebuffer);
3675 }
3676}
3677
3678void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3679{
3680 ASSERT(target == GL_RENDERBUFFER);
3681 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003682 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003683 mGLState.setRenderbufferBinding(object);
3684}
3685
JiangYizhoubddc46b2016-12-09 09:50:51 +08003686void Context::texStorage2DMultisample(GLenum target,
3687 GLsizei samples,
3688 GLenum internalformat,
3689 GLsizei width,
3690 GLsizei height,
3691 GLboolean fixedsamplelocations)
3692{
3693 Extents size(width, height, 1);
3694 Texture *texture = getTargetTexture(target);
3695 handleError(texture->setStorageMultisample(target, samples, internalformat, size,
3696 fixedsamplelocations));
3697}
3698
3699void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3700{
3701 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3702 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3703
3704 switch (pname)
3705 {
3706 case GL_SAMPLE_POSITION:
3707 handleError(framebuffer->getSamplePosition(index, val));
3708 break;
3709 default:
3710 UNREACHABLE();
3711 }
3712}
3713
Jamie Madillc29968b2016-01-20 11:17:23 -05003714} // namespace gl