blob: 7abacf490e5f66835c8e6bb29a3a71c5fbcc0db6 [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
Jamie Madill70ee0f62017-02-06 16:04:20 -0500384void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000385{
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
Jamie Madill70ee0f62017-02-06 16:04:20 -0500422 releaseSurface(display);
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
Jamie Madill70ee0f62017-02-06 16:04:20 -0500427Context::~Context()
428{
429}
430
431void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000432{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000433 if (!mHasBeenCurrent)
434 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500436 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400437 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438
Corentin Wallezc295e512017-01-27 17:47:50 -0500439 int width = 0;
440 int height = 0;
441 if (surface != nullptr)
442 {
443 width = surface->getWidth();
444 height = surface->getHeight();
445 }
446
447 mGLState.setViewportParams(0, 0, width, height);
448 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000449
450 mHasBeenCurrent = true;
451 }
452
Jamie Madill1b94d432015-08-07 13:23:23 -0400453 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700454 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400455
Jamie Madill70ee0f62017-02-06 16:04:20 -0500456 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500457
458 Framebuffer *newDefault = nullptr;
459 if (surface != nullptr)
460 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500461 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500462 mCurrentSurface = surface;
463 newDefault = surface->getDefaultFramebuffer();
464 }
465 else
466 {
467 if (mSurfacelessFramebuffer == nullptr)
468 {
469 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
470 }
471
472 newDefault = mSurfacelessFramebuffer;
473 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000474
Corentin Wallez37c39792015-08-20 14:19:46 -0400475 // Update default framebuffer, the binding of the previous default
476 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400477 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700478 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400479 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700480 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400481 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700482 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400483 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700484 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400485 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500486 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400487 }
Ian Ewell292f0052016-02-04 10:37:32 -0500488
489 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700490 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000491}
492
Jamie Madill70ee0f62017-02-06 16:04:20 -0500493void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400494{
Corentin Wallez37c39792015-08-20 14:19:46 -0400495 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500496 Framebuffer *currentDefault = nullptr;
497 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400498 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500499 currentDefault = mCurrentSurface->getDefaultFramebuffer();
500 }
501 else if (mSurfacelessFramebuffer != nullptr)
502 {
503 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400504 }
505
Corentin Wallezc295e512017-01-27 17:47:50 -0500506 if (mGLState.getReadFramebuffer() == currentDefault)
507 {
508 mGLState.setReadFramebufferBinding(nullptr);
509 }
510 if (mGLState.getDrawFramebuffer() == currentDefault)
511 {
512 mGLState.setDrawFramebufferBinding(nullptr);
513 }
514 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
515
516 if (mCurrentSurface)
517 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500518 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500519 mCurrentSurface = nullptr;
520 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400521}
522
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000523GLuint Context::createBuffer()
524{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500525 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000526}
527
528GLuint Context::createProgram()
529{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500530 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000531}
532
533GLuint Context::createShader(GLenum type)
534{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500535 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000536}
537
538GLuint Context::createTexture()
539{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500540 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000541}
542
543GLuint Context::createRenderbuffer()
544{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500545 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000546}
547
Geoff Lang882033e2014-09-30 11:26:07 -0400548GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400549{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500550 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400551
Cooper Partind8e62a32015-01-29 15:21:25 -0800552 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400553}
554
Sami Väisänene45e53b2016-05-25 10:36:04 +0300555GLuint Context::createPaths(GLsizei range)
556{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500557 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300558 if (resultOrError.isError())
559 {
560 handleError(resultOrError.getError());
561 return 0;
562 }
563 return resultOrError.getResult();
564}
565
Jamie Madill57a89722013-07-02 11:57:03 -0400566GLuint Context::createVertexArray()
567{
Geoff Lang36167ab2015-12-07 10:27:14 -0500568 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
569 mVertexArrayMap[vertexArray] = nullptr;
570 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400571}
572
Jamie Madilldc356042013-07-19 16:36:57 -0400573GLuint Context::createSampler()
574{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500575 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400576}
577
Geoff Langc8058452014-02-03 12:04:11 -0500578GLuint Context::createTransformFeedback()
579{
Geoff Lang36167ab2015-12-07 10:27:14 -0500580 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
581 mTransformFeedbackMap[transformFeedback] = nullptr;
582 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500583}
584
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585// Returns an unused framebuffer name
586GLuint Context::createFramebuffer()
587{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500588 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000589}
590
Jamie Madill33dc8432013-07-26 11:55:05 -0400591GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592{
Jamie Madill33dc8432013-07-26 11:55:05 -0400593 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000594
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400595 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000596
597 return handle;
598}
599
600// Returns an unused query name
601GLuint Context::createQuery()
602{
603 GLuint handle = mQueryHandleAllocator.allocate();
604
605 mQueryMap[handle] = NULL;
606
607 return handle;
608}
609
610void Context::deleteBuffer(GLuint buffer)
611{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500612 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000613 {
614 detachBuffer(buffer);
615 }
Jamie Madill893ab082014-05-16 16:56:10 -0400616
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500617 mState.mBuffers->deleteBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000618}
619
620void Context::deleteShader(GLuint shader)
621{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500622 mState.mShaderPrograms->deleteShader(shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000623}
624
625void Context::deleteProgram(GLuint program)
626{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500627 mState.mShaderPrograms->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000628}
629
630void Context::deleteTexture(GLuint texture)
631{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500632 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633 {
634 detachTexture(texture);
635 }
636
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500637 mState.mTextures->deleteTexture(texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000638}
639
640void Context::deleteRenderbuffer(GLuint renderbuffer)
641{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500642 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000643 {
644 detachRenderbuffer(renderbuffer);
645 }
Jamie Madill893ab082014-05-16 16:56:10 -0400646
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500647 mState.mRenderbuffers->deleteRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000648}
649
Jamie Madillcd055f82013-07-26 11:55:15 -0400650void Context::deleteFenceSync(GLsync fenceSync)
651{
652 // The spec specifies the underlying Fence object is not deleted until all current
653 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
654 // and since our API is currently designed for being called from a single thread, we can delete
655 // the fence immediately.
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500656 mState.mFenceSyncs->deleteFenceSync(
657 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400658}
659
Sami Väisänene45e53b2016-05-25 10:36:04 +0300660void Context::deletePaths(GLuint first, GLsizei range)
661{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500662 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300663}
664
665bool Context::hasPathData(GLuint path) const
666{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500667 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300668 if (pathObj == nullptr)
669 return false;
670
671 return pathObj->hasPathData();
672}
673
674bool Context::hasPath(GLuint path) const
675{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500676 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300677}
678
679void Context::setPathCommands(GLuint path,
680 GLsizei numCommands,
681 const GLubyte *commands,
682 GLsizei numCoords,
683 GLenum coordType,
684 const void *coords)
685{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500686 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300687
688 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
689}
690
691void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
692{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500693 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300694
695 switch (pname)
696 {
697 case GL_PATH_STROKE_WIDTH_CHROMIUM:
698 pathObj->setStrokeWidth(value);
699 break;
700 case GL_PATH_END_CAPS_CHROMIUM:
701 pathObj->setEndCaps(static_cast<GLenum>(value));
702 break;
703 case GL_PATH_JOIN_STYLE_CHROMIUM:
704 pathObj->setJoinStyle(static_cast<GLenum>(value));
705 break;
706 case GL_PATH_MITER_LIMIT_CHROMIUM:
707 pathObj->setMiterLimit(value);
708 break;
709 case GL_PATH_STROKE_BOUND_CHROMIUM:
710 pathObj->setStrokeBound(value);
711 break;
712 default:
713 UNREACHABLE();
714 break;
715 }
716}
717
718void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
719{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500720 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300721
722 switch (pname)
723 {
724 case GL_PATH_STROKE_WIDTH_CHROMIUM:
725 *value = pathObj->getStrokeWidth();
726 break;
727 case GL_PATH_END_CAPS_CHROMIUM:
728 *value = static_cast<GLfloat>(pathObj->getEndCaps());
729 break;
730 case GL_PATH_JOIN_STYLE_CHROMIUM:
731 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
732 break;
733 case GL_PATH_MITER_LIMIT_CHROMIUM:
734 *value = pathObj->getMiterLimit();
735 break;
736 case GL_PATH_STROKE_BOUND_CHROMIUM:
737 *value = pathObj->getStrokeBound();
738 break;
739 default:
740 UNREACHABLE();
741 break;
742 }
743}
744
745void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
746{
747 mGLState.setPathStencilFunc(func, ref, mask);
748}
749
Jamie Madill57a89722013-07-02 11:57:03 -0400750void Context::deleteVertexArray(GLuint vertexArray)
751{
Geoff Lang36167ab2015-12-07 10:27:14 -0500752 auto iter = mVertexArrayMap.find(vertexArray);
753 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000754 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500755 VertexArray *vertexArrayObject = iter->second;
756 if (vertexArrayObject != nullptr)
757 {
758 detachVertexArray(vertexArray);
759 delete vertexArrayObject;
760 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000761
Geoff Lang36167ab2015-12-07 10:27:14 -0500762 mVertexArrayMap.erase(iter);
763 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400764 }
765}
766
Jamie Madilldc356042013-07-19 16:36:57 -0400767void Context::deleteSampler(GLuint sampler)
768{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500769 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400770 {
771 detachSampler(sampler);
772 }
773
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500774 mState.mSamplers->deleteSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400775}
776
Geoff Langc8058452014-02-03 12:04:11 -0500777void Context::deleteTransformFeedback(GLuint transformFeedback)
778{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500779 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500780 if (iter != mTransformFeedbackMap.end())
781 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500782 TransformFeedback *transformFeedbackObject = iter->second;
783 if (transformFeedbackObject != nullptr)
784 {
785 detachTransformFeedback(transformFeedback);
786 transformFeedbackObject->release();
787 }
788
Geoff Lang50b3fe82015-12-08 14:49:12 +0000789 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500790 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500791 }
792}
793
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794void Context::deleteFramebuffer(GLuint framebuffer)
795{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500796 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000797 {
798 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000799 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500800
801 mState.mFramebuffers->deleteFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000802}
803
Jamie Madill33dc8432013-07-26 11:55:05 -0400804void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500806 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000807
Jamie Madill33dc8432013-07-26 11:55:05 -0400808 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000809 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400810 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000811 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400812 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813 }
814}
815
816void Context::deleteQuery(GLuint query)
817{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500818 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000819 if (queryObject != mQueryMap.end())
820 {
821 mQueryHandleAllocator.release(queryObject->first);
822 if (queryObject->second)
823 {
824 queryObject->second->release();
825 }
826 mQueryMap.erase(queryObject);
827 }
828}
829
Geoff Lang70d0f492015-12-10 17:45:46 -0500830Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000831{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500832 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000833}
834
Jamie Madill570f7c82014-07-03 10:38:54 -0400835Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000836{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500837 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000838}
839
Geoff Lang70d0f492015-12-10 17:45:46 -0500840Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000841{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500842 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843}
844
Jamie Madillcd055f82013-07-26 11:55:15 -0400845FenceSync *Context::getFenceSync(GLsync handle) const
846{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500847 return mState.mFenceSyncs->getFenceSync(
848 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400849}
850
Jamie Madill57a89722013-07-02 11:57:03 -0400851VertexArray *Context::getVertexArray(GLuint handle) const
852{
853 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500854 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400855}
856
Jamie Madilldc356042013-07-19 16:36:57 -0400857Sampler *Context::getSampler(GLuint handle) const
858{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500859 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400860}
861
Geoff Langc8058452014-02-03 12:04:11 -0500862TransformFeedback *Context::getTransformFeedback(GLuint handle) const
863{
Geoff Lang36167ab2015-12-07 10:27:14 -0500864 auto iter = mTransformFeedbackMap.find(handle);
865 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500866}
867
Geoff Lang70d0f492015-12-10 17:45:46 -0500868LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
869{
870 switch (identifier)
871 {
872 case GL_BUFFER:
873 return getBuffer(name);
874 case GL_SHADER:
875 return getShader(name);
876 case GL_PROGRAM:
877 return getProgram(name);
878 case GL_VERTEX_ARRAY:
879 return getVertexArray(name);
880 case GL_QUERY:
881 return getQuery(name);
882 case GL_TRANSFORM_FEEDBACK:
883 return getTransformFeedback(name);
884 case GL_SAMPLER:
885 return getSampler(name);
886 case GL_TEXTURE:
887 return getTexture(name);
888 case GL_RENDERBUFFER:
889 return getRenderbuffer(name);
890 case GL_FRAMEBUFFER:
891 return getFramebuffer(name);
892 default:
893 UNREACHABLE();
894 return nullptr;
895 }
896}
897
898LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
899{
900 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
901}
902
Martin Radev9d901792016-07-15 15:58:58 +0300903void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
904{
905 LabeledObject *object = getLabeledObject(identifier, name);
906 ASSERT(object != nullptr);
907
908 std::string labelName = GetObjectLabelFromPointer(length, label);
909 object->setLabel(labelName);
910}
911
912void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
913{
914 LabeledObject *object = getLabeledObjectFromPtr(ptr);
915 ASSERT(object != nullptr);
916
917 std::string labelName = GetObjectLabelFromPointer(length, label);
918 object->setLabel(labelName);
919}
920
921void Context::getObjectLabel(GLenum identifier,
922 GLuint name,
923 GLsizei bufSize,
924 GLsizei *length,
925 GLchar *label) const
926{
927 LabeledObject *object = getLabeledObject(identifier, name);
928 ASSERT(object != nullptr);
929
930 const std::string &objectLabel = object->getLabel();
931 GetObjectLabelBase(objectLabel, bufSize, length, label);
932}
933
934void Context::getObjectPtrLabel(const void *ptr,
935 GLsizei bufSize,
936 GLsizei *length,
937 GLchar *label) const
938{
939 LabeledObject *object = getLabeledObjectFromPtr(ptr);
940 ASSERT(object != nullptr);
941
942 const std::string &objectLabel = object->getLabel();
943 GetObjectLabelBase(objectLabel, bufSize, length, label);
944}
945
Jamie Madilldc356042013-07-19 16:36:57 -0400946bool Context::isSampler(GLuint samplerName) const
947{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500948 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400949}
950
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500951void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500953 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700954 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955}
956
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800957void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
958{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500959 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800960 mGLState.setDrawIndirectBufferBinding(buffer);
961}
962
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500963void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000964{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500965 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700966 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000967}
968
Jamie Madilldedd7b92014-11-05 16:30:36 -0500969void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000970{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500971 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000972
Jamie Madilldedd7b92014-11-05 16:30:36 -0500973 if (handle == 0)
974 {
975 texture = mZeroTextures[target].get();
976 }
977 else
978 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500979 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500980 }
981
982 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700983 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000984}
985
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500986void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500988 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
989 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700990 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000991}
992
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500993void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000994{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500995 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
996 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700997 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000998}
999
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001000void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001001{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001002 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001003 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001004}
1005
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001006void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001007{
Geoff Lang76b10c92014-09-05 16:28:14 -04001008 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001009 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001010 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001011 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001012}
1013
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001014void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001015{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001016 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001017 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001018}
1019
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001020void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1021 GLuint index,
1022 GLintptr offset,
1023 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001024{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001025 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001026 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001027}
1028
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001029void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001030{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001031 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001032 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001033}
1034
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001035void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1036 GLuint index,
1037 GLintptr offset,
1038 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001039{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001040 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001041 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001042}
1043
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001044void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001045{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001046 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001047 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001048}
1049
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001050void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001051{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001052 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001053 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001054}
1055
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001056void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001057{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001058 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001059 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001060}
1061
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001062void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001063{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001064 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001065 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001066}
1067
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068void Context::useProgram(GLuint program)
1069{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001070 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001071}
1072
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001073void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001074{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001075 TransformFeedback *transformFeedback =
1076 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001077 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001078}
1079
Geoff Lang5aad9672014-09-08 11:10:42 -04001080Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001081{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001082 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001083 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001084
Geoff Lang5aad9672014-09-08 11:10:42 -04001085 // begin query
1086 Error error = queryObject->begin();
1087 if (error.isError())
1088 {
1089 return error;
1090 }
1091
1092 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001093 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001094
He Yunchaoacd18982017-01-04 10:46:42 +08001095 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001096}
1097
Geoff Lang5aad9672014-09-08 11:10:42 -04001098Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001099{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001100 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001101 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001102
Geoff Lang5aad9672014-09-08 11:10:42 -04001103 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001104
Geoff Lang5aad9672014-09-08 11:10:42 -04001105 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001106 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001107
1108 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001109}
1110
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001111Error Context::queryCounter(GLuint id, GLenum target)
1112{
1113 ASSERT(target == GL_TIMESTAMP_EXT);
1114
1115 Query *queryObject = getQuery(id, true, target);
1116 ASSERT(queryObject);
1117
1118 return queryObject->queryCounter();
1119}
1120
1121void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1122{
1123 switch (pname)
1124 {
1125 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001126 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001127 break;
1128 case GL_QUERY_COUNTER_BITS_EXT:
1129 switch (target)
1130 {
1131 case GL_TIME_ELAPSED_EXT:
1132 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1133 break;
1134 case GL_TIMESTAMP_EXT:
1135 params[0] = getExtensions().queryCounterBitsTimestamp;
1136 break;
1137 default:
1138 UNREACHABLE();
1139 params[0] = 0;
1140 break;
1141 }
1142 break;
1143 default:
1144 UNREACHABLE();
1145 return;
1146 }
1147}
1148
Geoff Lang2186c382016-10-14 10:54:54 -04001149void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001150{
Geoff Lang2186c382016-10-14 10:54:54 -04001151 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001152}
1153
Geoff Lang2186c382016-10-14 10:54:54 -04001154void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001155{
Geoff Lang2186c382016-10-14 10:54:54 -04001156 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001157}
1158
Geoff Lang2186c382016-10-14 10:54:54 -04001159void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001160{
Geoff Lang2186c382016-10-14 10:54:54 -04001161 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001162}
1163
Geoff Lang2186c382016-10-14 10:54:54 -04001164void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001165{
Geoff Lang2186c382016-10-14 10:54:54 -04001166 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001167}
1168
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001169Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001170{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001171 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172}
1173
Jamie Madill33dc8432013-07-26 11:55:05 -04001174FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001176 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177
Jamie Madill33dc8432013-07-26 11:55:05 -04001178 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179 {
1180 return NULL;
1181 }
1182 else
1183 {
1184 return fence->second;
1185 }
1186}
1187
1188Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1189{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001190 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001191
1192 if (query == mQueryMap.end())
1193 {
1194 return NULL;
1195 }
1196 else
1197 {
1198 if (!query->second && create)
1199 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001200 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001201 query->second->addRef();
1202 }
1203 return query->second;
1204 }
1205}
1206
Geoff Lang70d0f492015-12-10 17:45:46 -05001207Query *Context::getQuery(GLuint handle) const
1208{
1209 auto iter = mQueryMap.find(handle);
1210 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1211}
1212
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001213Texture *Context::getTargetTexture(GLenum target) const
1214{
Ian Ewellbda75592016-04-18 17:25:54 -04001215 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001216 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001217}
1218
Geoff Lang76b10c92014-09-05 16:28:14 -04001219Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001220{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001221 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001222}
1223
Geoff Lang492a7e42014-11-05 13:27:06 -05001224Compiler *Context::getCompiler() const
1225{
1226 return mCompiler;
1227}
1228
Jamie Madill893ab082014-05-16 16:56:10 -04001229void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001230{
1231 switch (pname)
1232 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001233 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001234 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001236 mGLState.getBooleanv(pname, params);
1237 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001239}
1240
Jamie Madill893ab082014-05-16 16:56:10 -04001241void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242{
Shannon Woods53a94a82014-06-24 15:20:36 -04001243 // Queries about context capabilities and maximums are answered by Context.
1244 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001245 switch (pname)
1246 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001247 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001248 params[0] = mCaps.minAliasedLineWidth;
1249 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250 break;
1251 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001252 params[0] = mCaps.minAliasedPointSize;
1253 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001254 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001255 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001256 ASSERT(mExtensions.textureFilterAnisotropic);
1257 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001258 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001259 case GL_MAX_TEXTURE_LOD_BIAS:
1260 *params = mCaps.maxLODBias;
1261 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001262
1263 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1264 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1265 {
1266 ASSERT(mExtensions.pathRendering);
1267 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1268 memcpy(params, m, 16 * sizeof(GLfloat));
1269 }
1270 break;
1271
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001273 mGLState.getFloatv(pname, params);
1274 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276}
1277
Jamie Madill893ab082014-05-16 16:56:10 -04001278void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279{
Shannon Woods53a94a82014-06-24 15:20:36 -04001280 // Queries about context capabilities and maximums are answered by Context.
1281 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001282
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001283 switch (pname)
1284 {
Geoff Lang301d1612014-07-09 10:34:37 -04001285 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1286 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1287 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001288 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1289 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1290 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001291 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1292 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1293 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001294 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001295 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1296 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1297 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001298 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001299 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001300 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1301 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1302 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1303 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001304 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1305 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001306 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1307 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001308 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001309 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1310 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1311 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1312 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001313 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001314 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001315 break;
1316 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001317 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001318 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001319 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1320 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001321 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1322 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1323 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001324 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1325 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1326 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001327 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 case GL_MAX_VIEWPORT_DIMS:
1329 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001330 params[0] = mCaps.maxViewportWidth;
1331 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 }
1333 break;
1334 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001335 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001336 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001337 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1338 *params = mResetStrategy;
1339 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001340 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001341 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001342 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001343 case GL_SHADER_BINARY_FORMATS:
1344 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1345 break;
1346 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001347 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001348 break;
1349 case GL_PROGRAM_BINARY_FORMATS:
1350 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001351 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001352 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001353 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001354 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001355
1356 // GL_KHR_debug
1357 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1358 *params = mExtensions.maxDebugMessageLength;
1359 break;
1360 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1361 *params = mExtensions.maxDebugLoggedMessages;
1362 break;
1363 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1364 *params = mExtensions.maxDebugGroupStackDepth;
1365 break;
1366 case GL_MAX_LABEL_LENGTH:
1367 *params = mExtensions.maxLabelLength;
1368 break;
1369
Ian Ewell53f59f42016-01-28 17:36:55 -05001370 // GL_EXT_disjoint_timer_query
1371 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001372 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001373 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001374 case GL_MAX_FRAMEBUFFER_WIDTH:
1375 *params = mCaps.maxFramebufferWidth;
1376 break;
1377 case GL_MAX_FRAMEBUFFER_HEIGHT:
1378 *params = mCaps.maxFramebufferHeight;
1379 break;
1380 case GL_MAX_FRAMEBUFFER_SAMPLES:
1381 *params = mCaps.maxFramebufferSamples;
1382 break;
1383 case GL_MAX_SAMPLE_MASK_WORDS:
1384 *params = mCaps.maxSampleMaskWords;
1385 break;
1386 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1387 *params = mCaps.maxColorTextureSamples;
1388 break;
1389 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1390 *params = mCaps.maxDepthTextureSamples;
1391 break;
1392 case GL_MAX_INTEGER_SAMPLES:
1393 *params = mCaps.maxIntegerSamples;
1394 break;
1395 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1396 *params = mCaps.maxVertexAttribRelativeOffset;
1397 break;
1398 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1399 *params = mCaps.maxVertexAttribBindings;
1400 break;
1401 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1402 *params = mCaps.maxVertexAttribStride;
1403 break;
1404 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1405 *params = mCaps.maxVertexAtomicCounterBuffers;
1406 break;
1407 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1408 *params = mCaps.maxVertexAtomicCounters;
1409 break;
1410 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1411 *params = mCaps.maxVertexImageUniforms;
1412 break;
1413 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1414 *params = mCaps.maxVertexShaderStorageBlocks;
1415 break;
1416 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1417 *params = mCaps.maxFragmentAtomicCounterBuffers;
1418 break;
1419 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1420 *params = mCaps.maxFragmentAtomicCounters;
1421 break;
1422 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1423 *params = mCaps.maxFragmentImageUniforms;
1424 break;
1425 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1426 *params = mCaps.maxFragmentShaderStorageBlocks;
1427 break;
1428 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1429 *params = mCaps.minProgramTextureGatherOffset;
1430 break;
1431 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1432 *params = mCaps.maxProgramTextureGatherOffset;
1433 break;
1434 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1435 *params = mCaps.maxComputeWorkGroupInvocations;
1436 break;
1437 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1438 *params = mCaps.maxComputeUniformBlocks;
1439 break;
1440 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1441 *params = mCaps.maxComputeTextureImageUnits;
1442 break;
1443 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1444 *params = mCaps.maxComputeSharedMemorySize;
1445 break;
1446 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1447 *params = mCaps.maxComputeUniformComponents;
1448 break;
1449 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1450 *params = mCaps.maxComputeAtomicCounterBuffers;
1451 break;
1452 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1453 *params = mCaps.maxComputeAtomicCounters;
1454 break;
1455 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1456 *params = mCaps.maxComputeImageUniforms;
1457 break;
1458 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1459 *params = mCaps.maxCombinedComputeUniformComponents;
1460 break;
1461 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1462 *params = mCaps.maxComputeShaderStorageBlocks;
1463 break;
1464 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1465 *params = mCaps.maxCombinedShaderOutputResources;
1466 break;
1467 case GL_MAX_UNIFORM_LOCATIONS:
1468 *params = mCaps.maxUniformLocations;
1469 break;
1470 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1471 *params = mCaps.maxAtomicCounterBufferBindings;
1472 break;
1473 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1474 *params = mCaps.maxAtomicCounterBufferSize;
1475 break;
1476 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1477 *params = mCaps.maxCombinedAtomicCounterBuffers;
1478 break;
1479 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1480 *params = mCaps.maxCombinedAtomicCounters;
1481 break;
1482 case GL_MAX_IMAGE_UNITS:
1483 *params = mCaps.maxImageUnits;
1484 break;
1485 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1486 *params = mCaps.maxCombinedImageUniforms;
1487 break;
1488 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1489 *params = mCaps.maxShaderStorageBufferBindings;
1490 break;
1491 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1492 *params = mCaps.maxCombinedShaderStorageBlocks;
1493 break;
1494 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1495 *params = mCaps.shaderStorageBufferOffsetAlignment;
1496 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001497 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001498 mGLState.getIntegerv(mState, pname, params);
1499 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001500 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001501}
1502
Jamie Madill893ab082014-05-16 16:56:10 -04001503void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001504{
Shannon Woods53a94a82014-06-24 15:20:36 -04001505 // Queries about context capabilities and maximums are answered by Context.
1506 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001507 switch (pname)
1508 {
1509 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001510 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001511 break;
1512 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001513 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001514 break;
1515 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001516 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001517 break;
1518 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001519 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001520 break;
1521 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001522 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001523 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001524
1525 // GL_EXT_disjoint_timer_query
1526 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001527 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001528 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001529
1530 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1531 *params = mCaps.maxShaderStorageBlockSize;
1532 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001533 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001534 UNREACHABLE();
1535 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001536 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001537}
1538
Geoff Lang70d0f492015-12-10 17:45:46 -05001539void Context::getPointerv(GLenum pname, void **params) const
1540{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001541 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001542}
1543
Martin Radev66fb8202016-07-28 11:45:20 +03001544void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001545{
Shannon Woods53a94a82014-06-24 15:20:36 -04001546 // Queries about context capabilities and maximums are answered by Context.
1547 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001548
1549 GLenum nativeType;
1550 unsigned int numParams;
1551 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1552 ASSERT(queryStatus);
1553
1554 if (nativeType == GL_INT)
1555 {
1556 switch (target)
1557 {
1558 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1559 ASSERT(index < 3u);
1560 *data = mCaps.maxComputeWorkGroupCount[index];
1561 break;
1562 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1563 ASSERT(index < 3u);
1564 *data = mCaps.maxComputeWorkGroupSize[index];
1565 break;
1566 default:
1567 mGLState.getIntegeri_v(target, index, data);
1568 }
1569 }
1570 else
1571 {
1572 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1573 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001574}
1575
Martin Radev66fb8202016-07-28 11:45:20 +03001576void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001577{
Shannon Woods53a94a82014-06-24 15:20:36 -04001578 // Queries about context capabilities and maximums are answered by Context.
1579 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001580
1581 GLenum nativeType;
1582 unsigned int numParams;
1583 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1584 ASSERT(queryStatus);
1585
1586 if (nativeType == GL_INT_64_ANGLEX)
1587 {
1588 mGLState.getInteger64i_v(target, index, data);
1589 }
1590 else
1591 {
1592 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1593 }
1594}
1595
1596void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1597{
1598 // Queries about context capabilities and maximums are answered by Context.
1599 // Queries about current GL state values are answered by State.
1600
1601 GLenum nativeType;
1602 unsigned int numParams;
1603 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1604 ASSERT(queryStatus);
1605
1606 if (nativeType == GL_BOOL)
1607 {
1608 mGLState.getBooleani_v(target, index, data);
1609 }
1610 else
1611 {
1612 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1613 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001614}
1615
Jamie Madill675fe712016-12-19 13:07:54 -05001616void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001617{
Jamie Madill1b94d432015-08-07 13:23:23 -04001618 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001619 auto error = mImplementation->drawArrays(mode, first, count);
1620 handleError(error);
1621 if (!error.isError())
1622 {
1623 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1624 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001625}
1626
Jamie Madill675fe712016-12-19 13:07:54 -05001627void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001628{
1629 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001630 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1631 handleError(error);
1632 if (!error.isError())
1633 {
1634 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1635 }
Geoff Langf6db0982015-08-25 13:04:00 -04001636}
1637
Jamie Madill675fe712016-12-19 13:07:54 -05001638void Context::drawElements(GLenum mode,
1639 GLsizei count,
1640 GLenum type,
1641 const GLvoid *indices,
1642 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001643{
Jamie Madill1b94d432015-08-07 13:23:23 -04001644 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001645 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001646}
1647
Jamie Madill675fe712016-12-19 13:07:54 -05001648void Context::drawElementsInstanced(GLenum mode,
1649 GLsizei count,
1650 GLenum type,
1651 const GLvoid *indices,
1652 GLsizei instances,
1653 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001654{
1655 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001656 handleError(
1657 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001658}
1659
Jamie Madill675fe712016-12-19 13:07:54 -05001660void Context::drawRangeElements(GLenum mode,
1661 GLuint start,
1662 GLuint end,
1663 GLsizei count,
1664 GLenum type,
1665 const GLvoid *indices,
1666 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001667{
1668 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001669 handleError(
1670 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001671}
1672
Jiajia Qind9671222016-11-29 16:30:31 +08001673void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1674{
1675 syncRendererState();
1676 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1677}
1678
1679void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1680{
1681 syncRendererState();
1682 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1683}
1684
Jamie Madill675fe712016-12-19 13:07:54 -05001685void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001686{
Jamie Madill675fe712016-12-19 13:07:54 -05001687 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001688}
1689
Jamie Madill675fe712016-12-19 13:07:54 -05001690void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001691{
Jamie Madill675fe712016-12-19 13:07:54 -05001692 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001693}
1694
Austin Kinross6ee1e782015-05-29 17:05:37 -07001695void Context::insertEventMarker(GLsizei length, const char *marker)
1696{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001697 ASSERT(mImplementation);
1698 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001699}
1700
1701void Context::pushGroupMarker(GLsizei length, const char *marker)
1702{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001703 ASSERT(mImplementation);
1704 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001705}
1706
1707void Context::popGroupMarker()
1708{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001709 ASSERT(mImplementation);
1710 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001711}
1712
Geoff Langd8605522016-04-13 10:19:12 -04001713void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1714{
1715 Program *programObject = getProgram(program);
1716 ASSERT(programObject);
1717
1718 programObject->bindUniformLocation(location, name);
1719}
1720
Sami Väisänena797e062016-05-12 15:23:40 +03001721void Context::setCoverageModulation(GLenum components)
1722{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001723 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001724}
1725
Sami Väisänene45e53b2016-05-25 10:36:04 +03001726void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1727{
1728 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1729}
1730
1731void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1732{
1733 GLfloat I[16];
1734 angle::Matrix<GLfloat>::setToIdentity(I);
1735
1736 mGLState.loadPathRenderingMatrix(matrixMode, I);
1737}
1738
1739void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1740{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001741 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001742 if (!pathObj)
1743 return;
1744
1745 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1746 syncRendererState();
1747
1748 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1749}
1750
1751void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1752{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001753 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001754 if (!pathObj)
1755 return;
1756
1757 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1758 syncRendererState();
1759
1760 mImplementation->stencilStrokePath(pathObj, reference, mask);
1761}
1762
1763void Context::coverFillPath(GLuint path, GLenum coverMode)
1764{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001765 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001766 if (!pathObj)
1767 return;
1768
1769 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1770 syncRendererState();
1771
1772 mImplementation->coverFillPath(pathObj, coverMode);
1773}
1774
1775void Context::coverStrokePath(GLuint path, GLenum coverMode)
1776{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001777 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001778 if (!pathObj)
1779 return;
1780
1781 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1782 syncRendererState();
1783
1784 mImplementation->coverStrokePath(pathObj, coverMode);
1785}
1786
1787void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1788{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001789 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001790 if (!pathObj)
1791 return;
1792
1793 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1794 syncRendererState();
1795
1796 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1797}
1798
1799void Context::stencilThenCoverStrokePath(GLuint path,
1800 GLint reference,
1801 GLuint mask,
1802 GLenum coverMode)
1803{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001804 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001805 if (!pathObj)
1806 return;
1807
1808 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1809 syncRendererState();
1810
1811 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1812}
1813
Sami Väisänend59ca052016-06-21 16:10:00 +03001814void Context::coverFillPathInstanced(GLsizei numPaths,
1815 GLenum pathNameType,
1816 const void *paths,
1817 GLuint pathBase,
1818 GLenum coverMode,
1819 GLenum transformType,
1820 const GLfloat *transformValues)
1821{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001822 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001823
1824 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1825 syncRendererState();
1826
1827 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1828}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001829
Sami Väisänend59ca052016-06-21 16:10:00 +03001830void Context::coverStrokePathInstanced(GLsizei numPaths,
1831 GLenum pathNameType,
1832 const void *paths,
1833 GLuint pathBase,
1834 GLenum coverMode,
1835 GLenum transformType,
1836 const GLfloat *transformValues)
1837{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001838 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001839
1840 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1841 syncRendererState();
1842
1843 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1844 transformValues);
1845}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001846
Sami Väisänend59ca052016-06-21 16:10:00 +03001847void Context::stencilFillPathInstanced(GLsizei numPaths,
1848 GLenum pathNameType,
1849 const void *paths,
1850 GLuint pathBase,
1851 GLenum fillMode,
1852 GLuint mask,
1853 GLenum transformType,
1854 const GLfloat *transformValues)
1855{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001856 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001857
1858 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1859 syncRendererState();
1860
1861 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1862 transformValues);
1863}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001864
Sami Väisänend59ca052016-06-21 16:10:00 +03001865void Context::stencilStrokePathInstanced(GLsizei numPaths,
1866 GLenum pathNameType,
1867 const void *paths,
1868 GLuint pathBase,
1869 GLint reference,
1870 GLuint mask,
1871 GLenum transformType,
1872 const GLfloat *transformValues)
1873{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001874 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001875
1876 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1877 syncRendererState();
1878
1879 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1880 transformValues);
1881}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001882
Sami Väisänend59ca052016-06-21 16:10:00 +03001883void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1884 GLenum pathNameType,
1885 const void *paths,
1886 GLuint pathBase,
1887 GLenum fillMode,
1888 GLuint mask,
1889 GLenum coverMode,
1890 GLenum transformType,
1891 const GLfloat *transformValues)
1892{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001893 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001894
1895 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1896 syncRendererState();
1897
1898 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1899 transformType, transformValues);
1900}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001901
Sami Väisänend59ca052016-06-21 16:10:00 +03001902void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1903 GLenum pathNameType,
1904 const void *paths,
1905 GLuint pathBase,
1906 GLint reference,
1907 GLuint mask,
1908 GLenum coverMode,
1909 GLenum transformType,
1910 const GLfloat *transformValues)
1911{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001912 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001913
1914 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1915 syncRendererState();
1916
1917 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1918 transformType, transformValues);
1919}
1920
Sami Väisänen46eaa942016-06-29 10:26:37 +03001921void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1922{
1923 auto *programObject = getProgram(program);
1924
1925 programObject->bindFragmentInputLocation(location, name);
1926}
1927
1928void Context::programPathFragmentInputGen(GLuint program,
1929 GLint location,
1930 GLenum genMode,
1931 GLint components,
1932 const GLfloat *coeffs)
1933{
1934 auto *programObject = getProgram(program);
1935
1936 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1937}
1938
Jamie Madill437fa652016-05-03 15:13:24 -04001939void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001940{
Geoff Langda5777c2014-07-11 09:52:58 -04001941 if (error.isError())
1942 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001943 GLenum code = error.getCode();
1944 mErrors.insert(code);
1945 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1946 {
1947 markContextLost();
1948 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001949
1950 if (!error.getMessage().empty())
1951 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001952 auto *debug = &mGLState.getDebug();
1953 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1954 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001955 }
Geoff Langda5777c2014-07-11 09:52:58 -04001956 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001957}
1958
1959// Get one of the recorded errors and clear its flag, if any.
1960// [OpenGL ES 2.0.24] section 2.5 page 13.
1961GLenum Context::getError()
1962{
Geoff Langda5777c2014-07-11 09:52:58 -04001963 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001964 {
Geoff Langda5777c2014-07-11 09:52:58 -04001965 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001966 }
Geoff Langda5777c2014-07-11 09:52:58 -04001967 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001968 {
Geoff Langda5777c2014-07-11 09:52:58 -04001969 GLenum error = *mErrors.begin();
1970 mErrors.erase(mErrors.begin());
1971 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001972 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001973}
1974
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001975// NOTE: this function should not assume that this context is current!
1976void Context::markContextLost()
1977{
1978 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001979 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001980 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001981 mContextLostForced = true;
1982 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001983 mContextLost = true;
1984}
1985
1986bool Context::isContextLost()
1987{
1988 return mContextLost;
1989}
1990
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001991GLenum Context::getResetStatus()
1992{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001993 // Even if the application doesn't want to know about resets, we want to know
1994 // as it will allow us to skip all the calls.
1995 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001996 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001997 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001998 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001999 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002000 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002001
2002 // EXT_robustness, section 2.6: If the reset notification behavior is
2003 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2004 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2005 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002006 }
2007
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002008 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2009 // status should be returned at least once, and GL_NO_ERROR should be returned
2010 // once the device has finished resetting.
2011 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002012 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002013 ASSERT(mResetStatus == GL_NO_ERROR);
2014 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002015
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002016 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002017 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002018 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002019 }
2020 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002021 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002022 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002023 // If markContextLost was used to mark the context lost then
2024 // assume that is not recoverable, and continue to report the
2025 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002026 mResetStatus = mImplementation->getResetStatus();
2027 }
Jamie Madill893ab082014-05-16 16:56:10 -04002028
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002029 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002030}
2031
2032bool Context::isResetNotificationEnabled()
2033{
2034 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2035}
2036
Corentin Walleze3b10e82015-05-20 11:06:25 -04002037const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002038{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002039 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002040}
2041
2042EGLenum Context::getClientType() const
2043{
2044 return mClientType;
2045}
2046
2047EGLenum Context::getRenderBuffer() const
2048{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002049 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2050 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002051 {
2052 return EGL_NONE;
2053 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002054
2055 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2056 ASSERT(backAttachment != nullptr);
2057 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002058}
2059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002060VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002061{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002062 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002063 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2064 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002065 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002066 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2067
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002068 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002069 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002070
2071 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002072}
2073
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002074TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002075{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002076 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002077 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2078 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002079 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002080 transformFeedback =
2081 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002082 transformFeedback->addRef();
2083 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002084 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002085
2086 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002087}
2088
2089bool Context::isVertexArrayGenerated(GLuint vertexArray)
2090{
Geoff Langf41a7152016-09-19 15:11:17 -04002091 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002092 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2093}
2094
2095bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2096{
Geoff Langf41a7152016-09-19 15:11:17 -04002097 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002098 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2099}
2100
Shannon Woods53a94a82014-06-24 15:20:36 -04002101void Context::detachTexture(GLuint texture)
2102{
2103 // Simple pass-through to State's detachTexture method, as textures do not require
2104 // allocation map management either here or in the resource manager at detach time.
2105 // Zero textures are held by the Context, and we don't attempt to request them from
2106 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002107 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002108}
2109
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002110void Context::detachBuffer(GLuint buffer)
2111{
Yuly Novikov5807a532015-12-03 13:01:22 -05002112 // Simple pass-through to State's detachBuffer method, since
2113 // only buffer attachments to container objects that are bound to the current context
2114 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002115
Yuly Novikov5807a532015-12-03 13:01:22 -05002116 // [OpenGL ES 3.2] section 5.1.2 page 45:
2117 // Attachments to unbound container objects, such as
2118 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2119 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002120 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002121}
2122
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002123void Context::detachFramebuffer(GLuint framebuffer)
2124{
Shannon Woods53a94a82014-06-24 15:20:36 -04002125 // Framebuffer detachment is handled by Context, because 0 is a valid
2126 // Framebuffer object, and a pointer to it must be passed from Context
2127 // to State at binding time.
2128
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002129 // [OpenGL ES 2.0.24] section 4.4 page 107:
2130 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2131 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2132
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002133 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002134 {
2135 bindReadFramebuffer(0);
2136 }
2137
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002138 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002139 {
2140 bindDrawFramebuffer(0);
2141 }
2142}
2143
2144void Context::detachRenderbuffer(GLuint renderbuffer)
2145{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002146 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002147}
2148
Jamie Madill57a89722013-07-02 11:57:03 -04002149void Context::detachVertexArray(GLuint vertexArray)
2150{
Jamie Madill77a72f62015-04-14 11:18:32 -04002151 // Vertex array detachment is handled by Context, because 0 is a valid
2152 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002153 // binding time.
2154
Jamie Madill57a89722013-07-02 11:57:03 -04002155 // [OpenGL ES 3.0.2] section 2.10 page 43:
2156 // If a vertex array object that is currently bound is deleted, the binding
2157 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002158 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002159 {
2160 bindVertexArray(0);
2161 }
2162}
2163
Geoff Langc8058452014-02-03 12:04:11 -05002164void Context::detachTransformFeedback(GLuint transformFeedback)
2165{
Corentin Walleza2257da2016-04-19 16:43:12 -04002166 // Transform feedback detachment is handled by Context, because 0 is a valid
2167 // transform feedback, and a pointer to it must be passed from Context to State at
2168 // binding time.
2169
2170 // The OpenGL specification doesn't mention what should happen when the currently bound
2171 // transform feedback object is deleted. Since it is a container object, we treat it like
2172 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002173 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002174 {
2175 bindTransformFeedback(0);
2176 }
Geoff Langc8058452014-02-03 12:04:11 -05002177}
2178
Jamie Madilldc356042013-07-19 16:36:57 -04002179void Context::detachSampler(GLuint sampler)
2180{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002181 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002182}
2183
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002184void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2185{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002186 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002187}
2188
Jamie Madille29d1672013-07-19 16:36:57 -04002189void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2190{
Geoff Langc1984ed2016-10-07 12:41:00 -04002191 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002192 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002193 SetSamplerParameteri(samplerObject, pname, param);
2194}
Jamie Madille29d1672013-07-19 16:36:57 -04002195
Geoff Langc1984ed2016-10-07 12:41:00 -04002196void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2197{
2198 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002199 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002200 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002201}
2202
2203void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2204{
Geoff Langc1984ed2016-10-07 12:41:00 -04002205 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002206 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002207 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002208}
2209
Geoff Langc1984ed2016-10-07 12:41:00 -04002210void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002211{
Geoff Langc1984ed2016-10-07 12:41:00 -04002212 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002213 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002214 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002215}
2216
Geoff Langc1984ed2016-10-07 12:41:00 -04002217void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002218{
Geoff Langc1984ed2016-10-07 12:41:00 -04002219 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002220 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002221 QuerySamplerParameteriv(samplerObject, pname, params);
2222}
Jamie Madill9675b802013-07-19 16:36:59 -04002223
Geoff Langc1984ed2016-10-07 12:41:00 -04002224void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2225{
2226 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002227 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002228 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002229}
2230
Olli Etuahof0fee072016-03-30 15:11:58 +03002231void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2232{
2233 gl::Program *programObject = getProgram(program);
2234 ASSERT(programObject != nullptr);
2235
2236 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2237 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2238}
2239
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002240void Context::initRendererString()
2241{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002242 std::ostringstream rendererString;
2243 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002244 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002245 rendererString << ")";
2246
Geoff Langcec35902014-04-16 10:52:36 -04002247 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002248}
2249
Geoff Langc339c4e2016-11-29 10:37:36 -05002250void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002251{
Geoff Langc339c4e2016-11-29 10:37:36 -05002252 const Version &clientVersion = getClientVersion();
2253
2254 std::ostringstream versionString;
2255 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2256 << ANGLE_VERSION_STRING << ")";
2257 mVersionString = MakeStaticString(versionString.str());
2258
2259 std::ostringstream shadingLanguageVersionString;
2260 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2261 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2262 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2263 << ")";
2264 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002265}
2266
Geoff Langcec35902014-04-16 10:52:36 -04002267void Context::initExtensionStrings()
2268{
Geoff Langc339c4e2016-11-29 10:37:36 -05002269 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2270 std::ostringstream combinedStringStream;
2271 std::copy(strings.begin(), strings.end(),
2272 std::ostream_iterator<const char *>(combinedStringStream, " "));
2273 return MakeStaticString(combinedStringStream.str());
2274 };
2275
2276 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002277 for (const auto &extensionString : mExtensions.getStrings())
2278 {
2279 mExtensionStrings.push_back(MakeStaticString(extensionString));
2280 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002281 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002282
Bryan Bernhart58806562017-01-05 13:09:31 -08002283 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2284
Geoff Langc339c4e2016-11-29 10:37:36 -05002285 mRequestableExtensionStrings.clear();
2286 for (const auto &extensionInfo : GetExtensionInfoMap())
2287 {
2288 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002289 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2290 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002291 {
2292 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2293 }
2294 }
2295 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002296}
2297
Geoff Langc339c4e2016-11-29 10:37:36 -05002298const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002299{
Geoff Langc339c4e2016-11-29 10:37:36 -05002300 switch (name)
2301 {
2302 case GL_VENDOR:
2303 return reinterpret_cast<const GLubyte *>("Google Inc.");
2304
2305 case GL_RENDERER:
2306 return reinterpret_cast<const GLubyte *>(mRendererString);
2307
2308 case GL_VERSION:
2309 return reinterpret_cast<const GLubyte *>(mVersionString);
2310
2311 case GL_SHADING_LANGUAGE_VERSION:
2312 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2313
2314 case GL_EXTENSIONS:
2315 return reinterpret_cast<const GLubyte *>(mExtensionString);
2316
2317 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2318 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2319
2320 default:
2321 UNREACHABLE();
2322 return nullptr;
2323 }
Geoff Langcec35902014-04-16 10:52:36 -04002324}
2325
Geoff Langc339c4e2016-11-29 10:37:36 -05002326const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002327{
Geoff Langc339c4e2016-11-29 10:37:36 -05002328 switch (name)
2329 {
2330 case GL_EXTENSIONS:
2331 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2332
2333 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2334 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2335
2336 default:
2337 UNREACHABLE();
2338 return nullptr;
2339 }
Geoff Langcec35902014-04-16 10:52:36 -04002340}
2341
2342size_t Context::getExtensionStringCount() const
2343{
2344 return mExtensionStrings.size();
2345}
2346
Geoff Langc339c4e2016-11-29 10:37:36 -05002347void Context::requestExtension(const char *name)
2348{
2349 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2350 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2351 const auto &extension = extensionInfos.at(name);
2352 ASSERT(extension.Requestable);
2353
2354 if (mExtensions.*(extension.ExtensionsMember))
2355 {
2356 // Extension already enabled
2357 return;
2358 }
2359
2360 mExtensions.*(extension.ExtensionsMember) = true;
2361 updateCaps();
2362 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002363
2364 // Re-create the compiler with the requested extensions enabled.
2365 SafeDelete(mCompiler);
2366 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002367}
2368
2369size_t Context::getRequestableExtensionStringCount() const
2370{
2371 return mRequestableExtensionStrings.size();
2372}
2373
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002374void Context::beginTransformFeedback(GLenum primitiveMode)
2375{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002376 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002377 ASSERT(transformFeedback != nullptr);
2378 ASSERT(!transformFeedback->isPaused());
2379
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002380 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002381}
2382
2383bool Context::hasActiveTransformFeedback(GLuint program) const
2384{
2385 for (auto pair : mTransformFeedbackMap)
2386 {
2387 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2388 {
2389 return true;
2390 }
2391 }
2392 return false;
2393}
2394
Corentin Wallezc295e512017-01-27 17:47:50 -05002395void Context::initCaps(bool webGLContext, const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002396{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002397 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002398
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002399 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002400
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002401 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002402
Geoff Langeb66a6e2016-10-31 13:06:12 -04002403 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002404 {
2405 // Disable ES3+ extensions
2406 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002407 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002408 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002409 }
2410
Geoff Langeb66a6e2016-10-31 13:06:12 -04002411 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002412 {
2413 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2414 //mExtensions.sRGB = false;
2415 }
2416
Jamie Madill00ed7a12016-05-19 13:13:38 -04002417 // Some extensions are always available because they are implemented in the GL layer.
2418 mExtensions.bindUniformLocation = true;
2419 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002420 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002421 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002422
2423 // Enable the no error extension if the context was created with the flag.
2424 mExtensions.noError = mSkipValidation;
2425
Corentin Wallezccab69d2017-01-27 16:57:15 -05002426 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002427 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002428
Geoff Lang70d0f492015-12-10 17:45:46 -05002429 // Explicitly enable GL_KHR_debug
2430 mExtensions.debug = true;
2431 mExtensions.maxDebugMessageLength = 1024;
2432 mExtensions.maxDebugLoggedMessages = 1024;
2433 mExtensions.maxDebugGroupStackDepth = 1024;
2434 mExtensions.maxLabelLength = 1024;
2435
Geoff Langff5b2d52016-09-07 11:32:23 -04002436 // Explicitly enable GL_ANGLE_robust_client_memory
2437 mExtensions.robustClientMemory = true;
2438
Geoff Lang301d1612014-07-09 10:34:37 -04002439 // Apply implementation limits
2440 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002441 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2442 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2443
2444 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002445
Geoff Langc287ea62016-09-16 14:46:51 -04002446 // WebGL compatibility
2447 mExtensions.webglCompatibility = webGLContext;
2448 for (const auto &extensionInfo : GetExtensionInfoMap())
2449 {
2450 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002451 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002452 {
2453 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2454 }
2455 }
2456
2457 // Generate texture caps
2458 updateCaps();
2459}
2460
2461void Context::updateCaps()
2462{
Geoff Lang900013c2014-07-07 11:32:19 -04002463 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002464 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002465
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002466 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002467 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2468 {
2469 GLenum format = i->first;
2470 TextureCaps formatCaps = i->second;
2471
Geoff Lang5d601382014-07-22 15:14:06 -04002472 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002473
Geoff Lang0d8b7242015-09-09 14:56:53 -04002474 // Update the format caps based on the client version and extensions.
2475 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2476 // ES3.
2477 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002478 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002479 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002480 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002481 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002482 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002483
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002484 // OpenGL ES does not support multisampling with non-rendererable formats
2485 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2486 if (!formatInfo.renderSupport ||
2487 (getClientVersion() < ES_3_1 &&
2488 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002489 {
Geoff Langd87878e2014-09-19 15:42:59 -04002490 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002491 }
Geoff Langd87878e2014-09-19 15:42:59 -04002492
2493 if (formatCaps.texturable && formatInfo.compressed)
2494 {
2495 mCaps.compressedTextureFormats.push_back(format);
2496 }
2497
2498 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002499 }
2500}
2501
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002502void Context::initWorkarounds()
2503{
2504 // Lose the context upon out of memory error if the application is
2505 // expecting to watch for those events.
2506 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2507}
2508
Jamie Madill1b94d432015-08-07 13:23:23 -04002509void Context::syncRendererState()
2510{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002511 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2512 mImplementation->syncState(mGLState, dirtyBits);
2513 mGLState.clearDirtyBits();
2514 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002515}
2516
Jamie Madillad9f24e2016-02-12 09:27:24 -05002517void Context::syncRendererState(const State::DirtyBits &bitMask,
2518 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002519{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002520 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2521 mImplementation->syncState(mGLState, dirtyBits);
2522 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002523
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002524 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002525}
Jamie Madillc29968b2016-01-20 11:17:23 -05002526
2527void Context::blitFramebuffer(GLint srcX0,
2528 GLint srcY0,
2529 GLint srcX1,
2530 GLint srcY1,
2531 GLint dstX0,
2532 GLint dstY0,
2533 GLint dstX1,
2534 GLint dstY1,
2535 GLbitfield mask,
2536 GLenum filter)
2537{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002538 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002539 ASSERT(drawFramebuffer);
2540
2541 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2542 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2543
Jamie Madillad9f24e2016-02-12 09:27:24 -05002544 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002545
Jamie Madill8415b5f2016-04-26 13:41:39 -04002546 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002547}
Jamie Madillc29968b2016-01-20 11:17:23 -05002548
2549void Context::clear(GLbitfield mask)
2550{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002551 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002552 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002553}
2554
2555void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2556{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002557 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002558 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2559 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002560}
2561
2562void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2563{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002564 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002565 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2566 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002567}
2568
2569void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2570{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002571 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002572 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2573 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002574}
2575
2576void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2577{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002578 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002579 ASSERT(framebufferObject);
2580
2581 // If a buffer is not present, the clear has no effect
2582 if (framebufferObject->getDepthbuffer() == nullptr &&
2583 framebufferObject->getStencilbuffer() == nullptr)
2584 {
2585 return;
2586 }
2587
Jamie Madillad9f24e2016-02-12 09:27:24 -05002588 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002589 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2590 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002591}
2592
2593void Context::readPixels(GLint x,
2594 GLint y,
2595 GLsizei width,
2596 GLsizei height,
2597 GLenum format,
2598 GLenum type,
2599 GLvoid *pixels)
2600{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002601 if (width == 0 || height == 0)
2602 {
2603 return;
2604 }
2605
Jamie Madillad9f24e2016-02-12 09:27:24 -05002606 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002607
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002608 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002609 ASSERT(framebufferObject);
2610
2611 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002612 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002613}
2614
2615void Context::copyTexImage2D(GLenum target,
2616 GLint level,
2617 GLenum internalformat,
2618 GLint x,
2619 GLint y,
2620 GLsizei width,
2621 GLsizei height,
2622 GLint border)
2623{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002624 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002625 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002626
Jamie Madillc29968b2016-01-20 11:17:23 -05002627 Rectangle sourceArea(x, y, width, height);
2628
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002629 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002630 Texture *texture =
2631 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002632 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002633}
2634
2635void Context::copyTexSubImage2D(GLenum target,
2636 GLint level,
2637 GLint xoffset,
2638 GLint yoffset,
2639 GLint x,
2640 GLint y,
2641 GLsizei width,
2642 GLsizei height)
2643{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002644 if (width == 0 || height == 0)
2645 {
2646 return;
2647 }
2648
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002649 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002650 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002651
Jamie Madillc29968b2016-01-20 11:17:23 -05002652 Offset destOffset(xoffset, yoffset, 0);
2653 Rectangle sourceArea(x, y, width, height);
2654
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002655 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002656 Texture *texture =
2657 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002658 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002659}
2660
2661void Context::copyTexSubImage3D(GLenum target,
2662 GLint level,
2663 GLint xoffset,
2664 GLint yoffset,
2665 GLint zoffset,
2666 GLint x,
2667 GLint y,
2668 GLsizei width,
2669 GLsizei height)
2670{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002671 if (width == 0 || height == 0)
2672 {
2673 return;
2674 }
2675
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002676 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002677 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002678
Jamie Madillc29968b2016-01-20 11:17:23 -05002679 Offset destOffset(xoffset, yoffset, zoffset);
2680 Rectangle sourceArea(x, y, width, height);
2681
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002682 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002683 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002684 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002685}
2686
2687void Context::framebufferTexture2D(GLenum target,
2688 GLenum attachment,
2689 GLenum textarget,
2690 GLuint texture,
2691 GLint level)
2692{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002693 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002694 ASSERT(framebuffer);
2695
2696 if (texture != 0)
2697 {
2698 Texture *textureObj = getTexture(texture);
2699
2700 ImageIndex index = ImageIndex::MakeInvalid();
2701
2702 if (textarget == GL_TEXTURE_2D)
2703 {
2704 index = ImageIndex::Make2D(level);
2705 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002706 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2707 {
2708 ASSERT(level == 0);
2709 index = ImageIndex::Make2DMultisample();
2710 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002711 else
2712 {
2713 ASSERT(IsCubeMapTextureTarget(textarget));
2714 index = ImageIndex::MakeCube(textarget, level);
2715 }
2716
2717 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2718 }
2719 else
2720 {
2721 framebuffer->resetAttachment(attachment);
2722 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002723
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002724 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002725}
2726
2727void Context::framebufferRenderbuffer(GLenum target,
2728 GLenum attachment,
2729 GLenum renderbuffertarget,
2730 GLuint renderbuffer)
2731{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002732 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002733 ASSERT(framebuffer);
2734
2735 if (renderbuffer != 0)
2736 {
2737 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2738 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2739 renderbufferObject);
2740 }
2741 else
2742 {
2743 framebuffer->resetAttachment(attachment);
2744 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002745
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002746 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002747}
2748
2749void Context::framebufferTextureLayer(GLenum target,
2750 GLenum attachment,
2751 GLuint texture,
2752 GLint level,
2753 GLint layer)
2754{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002755 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002756 ASSERT(framebuffer);
2757
2758 if (texture != 0)
2759 {
2760 Texture *textureObject = getTexture(texture);
2761
2762 ImageIndex index = ImageIndex::MakeInvalid();
2763
2764 if (textureObject->getTarget() == GL_TEXTURE_3D)
2765 {
2766 index = ImageIndex::Make3D(level, layer);
2767 }
2768 else
2769 {
2770 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2771 index = ImageIndex::Make2DArray(level, layer);
2772 }
2773
2774 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2775 }
2776 else
2777 {
2778 framebuffer->resetAttachment(attachment);
2779 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002780
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002781 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002782}
2783
2784void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2785{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002786 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002787 ASSERT(framebuffer);
2788 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002789 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002790}
2791
2792void Context::readBuffer(GLenum mode)
2793{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002794 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002795 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002796 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002797}
2798
2799void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2800{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002801 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002802 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002803
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002804 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002805 ASSERT(framebuffer);
2806
2807 // The specification isn't clear what should be done when the framebuffer isn't complete.
2808 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002809 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002810}
2811
2812void Context::invalidateFramebuffer(GLenum target,
2813 GLsizei numAttachments,
2814 const GLenum *attachments)
2815{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002816 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002817 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002818
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002820 ASSERT(framebuffer);
2821
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002822 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002823 {
Jamie Madill437fa652016-05-03 15:13:24 -04002824 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002825 }
Jamie Madill437fa652016-05-03 15:13:24 -04002826
2827 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002828}
2829
2830void Context::invalidateSubFramebuffer(GLenum target,
2831 GLsizei numAttachments,
2832 const GLenum *attachments,
2833 GLint x,
2834 GLint y,
2835 GLsizei width,
2836 GLsizei height)
2837{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002838 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002839 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002840
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002841 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002842 ASSERT(framebuffer);
2843
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002844 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002845 {
Jamie Madill437fa652016-05-03 15:13:24 -04002846 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002847 }
Jamie Madill437fa652016-05-03 15:13:24 -04002848
2849 Rectangle area(x, y, width, height);
2850 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002851}
2852
Jamie Madill73a84962016-02-12 09:27:23 -05002853void Context::texImage2D(GLenum target,
2854 GLint level,
2855 GLint internalformat,
2856 GLsizei width,
2857 GLsizei height,
2858 GLint border,
2859 GLenum format,
2860 GLenum type,
2861 const GLvoid *pixels)
2862{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002863 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002864
2865 Extents size(width, height, 1);
2866 Texture *texture =
2867 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002868 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002869 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002870}
2871
2872void Context::texImage3D(GLenum target,
2873 GLint level,
2874 GLint internalformat,
2875 GLsizei width,
2876 GLsizei height,
2877 GLsizei depth,
2878 GLint border,
2879 GLenum format,
2880 GLenum type,
2881 const GLvoid *pixels)
2882{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002883 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002884
2885 Extents size(width, height, depth);
2886 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002887 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002888 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002889}
2890
2891void Context::texSubImage2D(GLenum target,
2892 GLint level,
2893 GLint xoffset,
2894 GLint yoffset,
2895 GLsizei width,
2896 GLsizei height,
2897 GLenum format,
2898 GLenum type,
2899 const GLvoid *pixels)
2900{
2901 // Zero sized uploads are valid but no-ops
2902 if (width == 0 || height == 0)
2903 {
2904 return;
2905 }
2906
Jamie Madillad9f24e2016-02-12 09:27:24 -05002907 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002908
2909 Box area(xoffset, yoffset, 0, width, height, 1);
2910 Texture *texture =
2911 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002912 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002913 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002914}
2915
2916void Context::texSubImage3D(GLenum target,
2917 GLint level,
2918 GLint xoffset,
2919 GLint yoffset,
2920 GLint zoffset,
2921 GLsizei width,
2922 GLsizei height,
2923 GLsizei depth,
2924 GLenum format,
2925 GLenum type,
2926 const GLvoid *pixels)
2927{
2928 // Zero sized uploads are valid but no-ops
2929 if (width == 0 || height == 0 || depth == 0)
2930 {
2931 return;
2932 }
2933
Jamie Madillad9f24e2016-02-12 09:27:24 -05002934 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002935
2936 Box area(xoffset, yoffset, zoffset, width, height, depth);
2937 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002938 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002939 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002940}
2941
2942void Context::compressedTexImage2D(GLenum target,
2943 GLint level,
2944 GLenum internalformat,
2945 GLsizei width,
2946 GLsizei height,
2947 GLint border,
2948 GLsizei imageSize,
2949 const GLvoid *data)
2950{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002951 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002952
2953 Extents size(width, height, 1);
2954 Texture *texture =
2955 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002956 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2957 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002958 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002959}
2960
2961void Context::compressedTexImage3D(GLenum target,
2962 GLint level,
2963 GLenum internalformat,
2964 GLsizei width,
2965 GLsizei height,
2966 GLsizei depth,
2967 GLint border,
2968 GLsizei imageSize,
2969 const GLvoid *data)
2970{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002971 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002972
2973 Extents size(width, height, depth);
2974 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002975 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2976 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002977 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002978}
2979
2980void Context::compressedTexSubImage2D(GLenum target,
2981 GLint level,
2982 GLint xoffset,
2983 GLint yoffset,
2984 GLsizei width,
2985 GLsizei height,
2986 GLenum format,
2987 GLsizei imageSize,
2988 const GLvoid *data)
2989{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002990 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002991
2992 Box area(xoffset, yoffset, 0, width, height, 1);
2993 Texture *texture =
2994 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002995 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2996 format, imageSize,
2997 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002998}
2999
3000void Context::compressedTexSubImage3D(GLenum target,
3001 GLint level,
3002 GLint xoffset,
3003 GLint yoffset,
3004 GLint zoffset,
3005 GLsizei width,
3006 GLsizei height,
3007 GLsizei depth,
3008 GLenum format,
3009 GLsizei imageSize,
3010 const GLvoid *data)
3011{
3012 // Zero sized uploads are valid but no-ops
3013 if (width == 0 || height == 0)
3014 {
3015 return;
3016 }
3017
Jamie Madillad9f24e2016-02-12 09:27:24 -05003018 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003019
3020 Box area(xoffset, yoffset, zoffset, width, height, depth);
3021 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003022 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3023 format, imageSize,
3024 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003025}
3026
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003027void Context::generateMipmap(GLenum target)
3028{
3029 Texture *texture = getTargetTexture(target);
3030 handleError(texture->generateMipmap());
3031}
3032
Geoff Lang97073d12016-04-20 10:42:34 -07003033void Context::copyTextureCHROMIUM(GLuint sourceId,
3034 GLuint destId,
3035 GLint internalFormat,
3036 GLenum destType,
3037 GLboolean unpackFlipY,
3038 GLboolean unpackPremultiplyAlpha,
3039 GLboolean unpackUnmultiplyAlpha)
3040{
3041 syncStateForTexImage();
3042
3043 gl::Texture *sourceTexture = getTexture(sourceId);
3044 gl::Texture *destTexture = getTexture(destId);
3045 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3046 unpackPremultiplyAlpha == GL_TRUE,
3047 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3048}
3049
3050void Context::copySubTextureCHROMIUM(GLuint sourceId,
3051 GLuint destId,
3052 GLint xoffset,
3053 GLint yoffset,
3054 GLint x,
3055 GLint y,
3056 GLsizei width,
3057 GLsizei height,
3058 GLboolean unpackFlipY,
3059 GLboolean unpackPremultiplyAlpha,
3060 GLboolean unpackUnmultiplyAlpha)
3061{
3062 // Zero sized copies are valid but no-ops
3063 if (width == 0 || height == 0)
3064 {
3065 return;
3066 }
3067
3068 syncStateForTexImage();
3069
3070 gl::Texture *sourceTexture = getTexture(sourceId);
3071 gl::Texture *destTexture = getTexture(destId);
3072 Offset offset(xoffset, yoffset, 0);
3073 Rectangle area(x, y, width, height);
3074 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3075 unpackPremultiplyAlpha == GL_TRUE,
3076 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3077}
3078
Geoff Lang47110bf2016-04-20 11:13:22 -07003079void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3080{
3081 syncStateForTexImage();
3082
3083 gl::Texture *sourceTexture = getTexture(sourceId);
3084 gl::Texture *destTexture = getTexture(destId);
3085 handleError(destTexture->copyCompressedTexture(sourceTexture));
3086}
3087
Geoff Lang496c02d2016-10-20 11:38:11 -07003088void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003089{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003090 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003091 ASSERT(buffer);
3092
Geoff Lang496c02d2016-10-20 11:38:11 -07003093 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003094}
3095
3096GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3097{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003098 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003099 ASSERT(buffer);
3100
3101 Error error = buffer->map(access);
3102 if (error.isError())
3103 {
Jamie Madill437fa652016-05-03 15:13:24 -04003104 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003105 return nullptr;
3106 }
3107
3108 return buffer->getMapPointer();
3109}
3110
3111GLboolean Context::unmapBuffer(GLenum target)
3112{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003113 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003114 ASSERT(buffer);
3115
3116 GLboolean result;
3117 Error error = buffer->unmap(&result);
3118 if (error.isError())
3119 {
Jamie Madill437fa652016-05-03 15:13:24 -04003120 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003121 return GL_FALSE;
3122 }
3123
3124 return result;
3125}
3126
3127GLvoid *Context::mapBufferRange(GLenum target,
3128 GLintptr offset,
3129 GLsizeiptr length,
3130 GLbitfield access)
3131{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003132 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003133 ASSERT(buffer);
3134
3135 Error error = buffer->mapRange(offset, length, access);
3136 if (error.isError())
3137 {
Jamie Madill437fa652016-05-03 15:13:24 -04003138 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003139 return nullptr;
3140 }
3141
3142 return buffer->getMapPointer();
3143}
3144
3145void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3146{
3147 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3148}
3149
Jamie Madillad9f24e2016-02-12 09:27:24 -05003150void Context::syncStateForReadPixels()
3151{
3152 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3153}
3154
3155void Context::syncStateForTexImage()
3156{
3157 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3158}
3159
3160void Context::syncStateForClear()
3161{
3162 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3163}
3164
3165void Context::syncStateForBlit()
3166{
3167 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3168}
3169
Jamie Madillc20ab272016-06-09 07:20:46 -07003170void Context::activeTexture(GLenum texture)
3171{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003172 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003173}
3174
3175void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3176{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003177 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003178}
3179
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003180void Context::blendEquation(GLenum mode)
3181{
3182 mGLState.setBlendEquation(mode, mode);
3183}
3184
Jamie Madillc20ab272016-06-09 07:20:46 -07003185void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3186{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003187 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003188}
3189
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003190void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3191{
3192 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3193}
3194
Jamie Madillc20ab272016-06-09 07:20:46 -07003195void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3196{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003197 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003198}
3199
3200void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3201{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003202 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003203}
3204
3205void Context::clearDepthf(GLclampf depth)
3206{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003207 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003208}
3209
3210void Context::clearStencil(GLint s)
3211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003212 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003213}
3214
3215void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003217 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003218}
3219
3220void Context::cullFace(GLenum mode)
3221{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003222 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003223}
3224
3225void Context::depthFunc(GLenum func)
3226{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003227 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003228}
3229
3230void Context::depthMask(GLboolean flag)
3231{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003232 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003233}
3234
3235void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3236{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003237 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003238}
3239
3240void Context::disable(GLenum cap)
3241{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003242 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003243}
3244
3245void Context::disableVertexAttribArray(GLuint index)
3246{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003247 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003248}
3249
3250void Context::enable(GLenum cap)
3251{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003252 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003253}
3254
3255void Context::enableVertexAttribArray(GLuint index)
3256{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003257 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003258}
3259
3260void Context::frontFace(GLenum mode)
3261{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003262 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003263}
3264
3265void Context::hint(GLenum target, GLenum mode)
3266{
3267 switch (target)
3268 {
3269 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003270 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003271 break;
3272
3273 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003274 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003275 break;
3276
3277 default:
3278 UNREACHABLE();
3279 return;
3280 }
3281}
3282
3283void Context::lineWidth(GLfloat width)
3284{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003285 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003286}
3287
3288void Context::pixelStorei(GLenum pname, GLint param)
3289{
3290 switch (pname)
3291 {
3292 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003293 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003294 break;
3295
3296 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003297 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003298 break;
3299
3300 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003301 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003302 break;
3303
3304 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003305 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003306 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003307 break;
3308
3309 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003310 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003311 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003312 break;
3313
3314 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003315 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003316 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003317 break;
3318
3319 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003320 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003321 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003322 break;
3323
3324 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003325 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003326 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003327 break;
3328
3329 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003330 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003331 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003332 break;
3333
3334 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003335 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003336 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003337 break;
3338
3339 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003340 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003341 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003342 break;
3343
3344 default:
3345 UNREACHABLE();
3346 return;
3347 }
3348}
3349
3350void Context::polygonOffset(GLfloat factor, GLfloat units)
3351{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003352 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003353}
3354
3355void Context::sampleCoverage(GLclampf value, GLboolean invert)
3356{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003357 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003358}
3359
3360void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3361{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003362 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003363}
3364
3365void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3366{
3367 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3368 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370 }
3371
3372 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3373 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003374 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003375 }
3376}
3377
3378void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3379{
3380 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3381 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003382 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003383 }
3384
3385 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3386 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003387 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003388 }
3389}
3390
3391void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3392{
3393 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3394 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003395 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003396 }
3397
3398 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3399 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003400 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003401 }
3402}
3403
3404void Context::vertexAttrib1f(GLuint index, GLfloat x)
3405{
3406 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003407 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003408}
3409
3410void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3411{
3412 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003414}
3415
3416void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3417{
3418 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420}
3421
3422void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3423{
3424 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003425 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003426}
3427
3428void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3429{
3430 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003431 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003432}
3433
3434void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3435{
3436 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003437 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003438}
3439
3440void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3441{
3442 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003443 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003444}
3445
3446void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3447{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003448 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003449}
3450
3451void Context::vertexAttribPointer(GLuint index,
3452 GLint size,
3453 GLenum type,
3454 GLboolean normalized,
3455 GLsizei stride,
3456 const GLvoid *ptr)
3457{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003458 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3459 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003460}
3461
3462void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3463{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003464 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003465}
3466
3467void Context::vertexAttribIPointer(GLuint index,
3468 GLint size,
3469 GLenum type,
3470 GLsizei stride,
3471 const GLvoid *pointer)
3472{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003473 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3474 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003475}
3476
3477void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3478{
3479 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003480 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003481}
3482
3483void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3484{
3485 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003486 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003487}
3488
3489void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3490{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003491 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003492}
3493
3494void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3495{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003496 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003497}
3498
3499void Context::debugMessageControl(GLenum source,
3500 GLenum type,
3501 GLenum severity,
3502 GLsizei count,
3503 const GLuint *ids,
3504 GLboolean enabled)
3505{
3506 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003507 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3508 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003509}
3510
3511void Context::debugMessageInsert(GLenum source,
3512 GLenum type,
3513 GLuint id,
3514 GLenum severity,
3515 GLsizei length,
3516 const GLchar *buf)
3517{
3518 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003519 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003520}
3521
3522void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3523{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003524 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003525}
3526
3527GLuint Context::getDebugMessageLog(GLuint count,
3528 GLsizei bufSize,
3529 GLenum *sources,
3530 GLenum *types,
3531 GLuint *ids,
3532 GLenum *severities,
3533 GLsizei *lengths,
3534 GLchar *messageLog)
3535{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003536 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3537 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003538}
3539
3540void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3541{
3542 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003543 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003544}
3545
3546void Context::popDebugGroup()
3547{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003548 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003549}
3550
Jamie Madill29639852016-09-02 15:00:09 -04003551void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3552{
3553 Buffer *buffer = mGLState.getTargetBuffer(target);
3554 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003555 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003556}
3557
3558void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3559{
3560 if (data == nullptr)
3561 {
3562 return;
3563 }
3564
3565 Buffer *buffer = mGLState.getTargetBuffer(target);
3566 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003567 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003568}
3569
Jamie Madillef300b12016-10-07 15:12:09 -04003570void Context::attachShader(GLuint program, GLuint shader)
3571{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003572 auto programObject = mState.mShaderPrograms->getProgram(program);
3573 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003574 ASSERT(programObject && shaderObject);
3575 programObject->attachShader(shaderObject);
3576}
3577
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003578const Workarounds &Context::getWorkarounds() const
3579{
3580 return mWorkarounds;
3581}
3582
Jamie Madillb0817d12016-11-01 15:48:31 -04003583void Context::copyBufferSubData(GLenum readTarget,
3584 GLenum writeTarget,
3585 GLintptr readOffset,
3586 GLintptr writeOffset,
3587 GLsizeiptr size)
3588{
3589 // if size is zero, the copy is a successful no-op
3590 if (size == 0)
3591 {
3592 return;
3593 }
3594
3595 // TODO(jmadill): cache these.
3596 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3597 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3598
3599 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3600}
3601
Jamie Madill01a80ee2016-11-07 12:06:18 -05003602void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3603{
3604 Program *programObject = getProgram(program);
3605 // TODO(jmadill): Re-use this from the validation if possible.
3606 ASSERT(programObject);
3607 programObject->bindAttributeLocation(index, name);
3608}
3609
3610void Context::bindBuffer(GLenum target, GLuint buffer)
3611{
3612 switch (target)
3613 {
3614 case GL_ARRAY_BUFFER:
3615 bindArrayBuffer(buffer);
3616 break;
3617 case GL_ELEMENT_ARRAY_BUFFER:
3618 bindElementArrayBuffer(buffer);
3619 break;
3620 case GL_COPY_READ_BUFFER:
3621 bindCopyReadBuffer(buffer);
3622 break;
3623 case GL_COPY_WRITE_BUFFER:
3624 bindCopyWriteBuffer(buffer);
3625 break;
3626 case GL_PIXEL_PACK_BUFFER:
3627 bindPixelPackBuffer(buffer);
3628 break;
3629 case GL_PIXEL_UNPACK_BUFFER:
3630 bindPixelUnpackBuffer(buffer);
3631 break;
3632 case GL_UNIFORM_BUFFER:
3633 bindGenericUniformBuffer(buffer);
3634 break;
3635 case GL_TRANSFORM_FEEDBACK_BUFFER:
3636 bindGenericTransformFeedbackBuffer(buffer);
3637 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003638 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003639 if (buffer != 0)
3640 {
3641 // Binding buffers to this binding point is not implemented yet.
3642 UNIMPLEMENTED();
3643 }
Geoff Lang3b573612016-10-31 14:08:10 -04003644 break;
3645 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003646 if (buffer != 0)
3647 {
3648 // Binding buffers to this binding point is not implemented yet.
3649 UNIMPLEMENTED();
3650 }
Geoff Lang3b573612016-10-31 14:08:10 -04003651 break;
3652 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003653 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003654 break;
3655 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003656 if (buffer != 0)
3657 {
3658 // Binding buffers to this binding point is not implemented yet.
3659 UNIMPLEMENTED();
3660 }
Geoff Lang3b573612016-10-31 14:08:10 -04003661 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003662
3663 default:
3664 UNREACHABLE();
3665 break;
3666 }
3667}
3668
3669void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3670{
3671 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3672 {
3673 bindReadFramebuffer(framebuffer);
3674 }
3675
3676 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3677 {
3678 bindDrawFramebuffer(framebuffer);
3679 }
3680}
3681
3682void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3683{
3684 ASSERT(target == GL_RENDERBUFFER);
3685 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003686 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003687 mGLState.setRenderbufferBinding(object);
3688}
3689
JiangYizhoubddc46b2016-12-09 09:50:51 +08003690void Context::texStorage2DMultisample(GLenum target,
3691 GLsizei samples,
3692 GLenum internalformat,
3693 GLsizei width,
3694 GLsizei height,
3695 GLboolean fixedsamplelocations)
3696{
3697 Extents size(width, height, 1);
3698 Texture *texture = getTargetTexture(target);
3699 handleError(texture->setStorageMultisample(target, samples, internalformat, size,
3700 fixedsamplelocations));
3701}
3702
3703void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3704{
3705 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3706 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3707
3708 switch (pname)
3709 {
3710 case GL_SAMPLE_POSITION:
3711 handleError(framebuffer->getSamplePosition(index, val));
3712 break;
3713 default:
3714 UNREACHABLE();
3715 }
3716}
3717
Jamie Madillc29968b2016-01-20 11:17:23 -05003718} // namespace gl