blob: 65152b9238ef24b9558aceb4a0d2e565c069aaab [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"
Jiawei-Shao2597fb62016-12-09 16:38:02 +080029#include "libANGLE/queryutils.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
37#include "libANGLE/formatutils.h"
38#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070039#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040040#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040041#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030042#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040043#include "libANGLE/queryutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Ian Ewell3ffd78b2016-01-22 16:09:42 -050048template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050049std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030050 GLsizei numPaths,
51 const void *paths,
52 GLuint pathBase)
53{
54 std::vector<gl::Path *> ret;
55 ret.reserve(numPaths);
56
57 const auto *nameArray = static_cast<const T *>(paths);
58
59 for (GLsizei i = 0; i < numPaths; ++i)
60 {
61 const GLuint pathName = nameArray[i] + pathBase;
62
63 ret.push_back(resourceManager.getPath(pathName));
64 }
65
66 return ret;
67}
68
Geoff Lang4ddf5af2016-12-01 14:30:44 -050069std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030070 GLsizei numPaths,
71 GLenum pathNameType,
72 const void *paths,
73 GLuint pathBase)
74{
75 switch (pathNameType)
76 {
77 case GL_UNSIGNED_BYTE:
78 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_BYTE:
81 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_UNSIGNED_SHORT:
84 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_SHORT:
87 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_INT:
90 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_INT:
93 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
94 }
95
96 UNREACHABLE();
97 return std::vector<gl::Path *>();
98}
99
100template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400101gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500102{
Geoff Lang2186c382016-10-14 10:54:54 -0400103 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500104
105 switch (pname)
106 {
107 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400108 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109 case GL_QUERY_RESULT_AVAILABLE_EXT:
110 {
111 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400112 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500113 if (!error.isError())
114 {
Geoff Lang2186c382016-10-14 10:54:54 -0400115 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500116 }
117 return error;
118 }
119 default:
120 UNREACHABLE();
121 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
122 }
123}
124
Geoff Langf6db0982015-08-25 13:04:00 -0400125void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
126{
Geoff Lang1a683462015-09-29 15:09:59 -0400127 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400128 {
129 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
130 tfBufferIndex++)
131 {
132 const OffsetBindingPointer<gl::Buffer> &buffer =
133 transformFeedback->getIndexedBuffer(tfBufferIndex);
134 if (buffer.get() != nullptr)
135 {
136 buffer->onTransformFeedback();
137 }
138 }
139 }
140}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141
142// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300143EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400145 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146}
147
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
149{
150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
151}
152
Geoff Langeb66a6e2016-10-31 13:06:12 -0400153gl::Version GetClientVersion(const egl::AttributeMap &attribs)
154{
155 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
156}
157
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500158GLenum GetResetStrategy(const egl::AttributeMap &attribs)
159{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400160 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
161 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500162 switch (attrib)
163 {
164 case EGL_NO_RESET_NOTIFICATION:
165 return GL_NO_RESET_NOTIFICATION_EXT;
166 case EGL_LOSE_CONTEXT_ON_RESET:
167 return GL_LOSE_CONTEXT_ON_RESET_EXT;
168 default:
169 UNREACHABLE();
170 return GL_NONE;
171 }
172}
173
174bool GetRobustAccess(const egl::AttributeMap &attribs)
175{
Geoff Lang077f20a2016-11-01 10:08:02 -0400176 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
177 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
178 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500179}
180
181bool GetDebug(const egl::AttributeMap &attribs)
182{
Geoff Lang077f20a2016-11-01 10:08:02 -0400183 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
184 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetNoError(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
190}
191
Geoff Langc287ea62016-09-16 14:46:51 -0400192bool GetWebGLContext(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langf41a7152016-09-19 15:11:17 -0400197bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
200}
201
Geoff Langfeb8c682017-02-13 16:07:35 -0500202bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
205}
206
Martin Radev9d901792016-07-15 15:58:58 +0300207std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
208{
209 std::string labelName;
210 if (label != nullptr)
211 {
212 size_t labelLength = length < 0 ? strlen(label) : length;
213 labelName = std::string(label, labelLength);
214 }
215 return labelName;
216}
217
218void GetObjectLabelBase(const std::string &objectLabel,
219 GLsizei bufSize,
220 GLsizei *length,
221 GLchar *label)
222{
223 size_t writeLength = objectLabel.length();
224 if (label != nullptr && bufSize > 0)
225 {
226 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
227 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
228 label[writeLength] = '\0';
229 }
230
231 if (length != nullptr)
232 {
233 *length = static_cast<GLsizei>(writeLength);
234 }
235}
236
Geoff Langf6db0982015-08-25 13:04:00 -0400237} // anonymous namespace
238
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000239namespace gl
240{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000241
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400242Context::Context(rx::EGLImplFactory *implFactory,
243 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400244 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500245 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500246 const egl::AttributeMap &attribs,
247 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300248
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500249 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500250 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500251 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700252 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500253 mCaps,
254 mTextureCaps,
255 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500256 mLimitations,
257 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700258 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500259 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400260 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500261 mClientType(EGL_OPENGL_ES_API),
262 mHasBeenCurrent(false),
263 mContextLost(false),
264 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700265 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500266 mResetStrategy(GetResetStrategy(attribs)),
267 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500268 mCurrentSurface(nullptr),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500269 mSurfacelessFramebuffer(nullptr),
270 mWebGLContext(GetWebGLContext(attribs))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000271{
Geoff Lang077f20a2016-11-01 10:08:02 -0400272 if (mRobustAccess)
273 {
274 UNIMPLEMENTED();
275 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500277 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700278 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400279
Geoff Langeb66a6e2016-10-31 13:06:12 -0400280 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langfeb8c682017-02-13 16:07:35 -0500281 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100282
Shannon Woods53a94a82014-06-24 15:20:36 -0400283 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400284
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000285 // [OpenGL ES 2.0.24] section 3.7 page 83:
286 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
287 // and cube map texture state vectors respectively associated with them.
288 // In order that access to these initial textures not be lost, they are treated as texture
289 // objects all of whose names are 0.
290
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400291 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500292 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400296
Geoff Langeb66a6e2016-10-31 13:06:12 -0400297 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400298 {
299 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400300 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500301 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400302
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500304 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400305 }
Geoff Lang3b573612016-10-31 14:08:10 -0400306 if (getClientVersion() >= Version(3, 1))
307 {
308 Texture *zeroTexture2DMultisample =
309 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
310 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
311 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000312
Ian Ewellbda75592016-04-18 17:25:54 -0400313 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
314 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400315 Texture *zeroTextureExternal =
316 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400317 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
318 }
319
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700320 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500321
Jamie Madill57a89722013-07-02 11:57:03 -0400322 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000323 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800324 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000325 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400326
Jamie Madill01a80ee2016-11-07 12:06:18 -0500327 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000328
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000329 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500330 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000331 {
332 bindIndexedUniformBuffer(0, i, 0, -1);
333 }
334
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000335 bindCopyReadBuffer(0);
336 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000337 bindPixelPackBuffer(0);
338 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000339
Geoff Langeb66a6e2016-10-31 13:06:12 -0400340 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400341 {
342 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
343 // In the initial state, a default transform feedback object is bound and treated as
344 // a transform feedback object with a name of zero. That object is bound any time
345 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400346 bindTransformFeedback(0);
347 }
Geoff Langc8058452014-02-03 12:04:11 -0500348
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700349 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500350
351 // Initialize dirty bit masks
352 // TODO(jmadill): additional ES3 state
353 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
354 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
355 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
356 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
357 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
358 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400359 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500360 // No dirty objects.
361
362 // Readpixels uses the pack state and read FBO
363 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
364 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
365 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
366 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
367 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400368 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500369 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
370
371 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
372 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
373 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
374 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
375 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
376 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
377 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
378 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
379 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
380 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
381 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
382 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
383
384 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
385 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700386 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500387 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
388 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400389
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400390 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000391}
392
Jamie Madill70ee0f62017-02-06 16:04:20 -0500393void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000394{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500395 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000396
Corentin Wallez80b24112015-08-25 16:41:57 -0400397 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000398 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400399 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000400 }
401
Corentin Wallez80b24112015-08-25 16:41:57 -0400402 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000403 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400404 if (query.second != nullptr)
405 {
406 query.second->release();
407 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000408 }
409
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400411 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400412 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400413 }
414
Corentin Wallez80b24112015-08-25 16:41:57 -0400415 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500416 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500417 if (transformFeedback.second != nullptr)
418 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500419 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500420 }
Geoff Langc8058452014-02-03 12:04:11 -0500421 }
422
Jamie Madilldedd7b92014-11-05 16:30:36 -0500423 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400424 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500425 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400426 }
427 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000428
Corentin Wallezccab69d2017-01-27 16:57:15 -0500429 SafeDelete(mSurfacelessFramebuffer);
430
Jamie Madill70ee0f62017-02-06 16:04:20 -0500431 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400432
Geoff Lang492a7e42014-11-05 13:27:06 -0500433 SafeDelete(mCompiler);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500434
435 mState.mBuffers->release(this);
436 mState.mShaderPrograms->release(this);
437 mState.mTextures->release(this);
438 mState.mRenderbuffers->release(this);
439 mState.mSamplers->release(this);
440 mState.mFenceSyncs->release(this);
441 mState.mPaths->release(this);
442 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000443}
444
Jamie Madill70ee0f62017-02-06 16:04:20 -0500445Context::~Context()
446{
447}
448
449void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000450{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000451 if (!mHasBeenCurrent)
452 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000453 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500454 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400455 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000456
Corentin Wallezc295e512017-01-27 17:47:50 -0500457 int width = 0;
458 int height = 0;
459 if (surface != nullptr)
460 {
461 width = surface->getWidth();
462 height = surface->getHeight();
463 }
464
465 mGLState.setViewportParams(0, 0, width, height);
466 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000467
468 mHasBeenCurrent = true;
469 }
470
Jamie Madill1b94d432015-08-07 13:23:23 -0400471 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700472 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400473
Jamie Madill70ee0f62017-02-06 16:04:20 -0500474 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500475
476 Framebuffer *newDefault = nullptr;
477 if (surface != nullptr)
478 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500479 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500480 mCurrentSurface = surface;
481 newDefault = surface->getDefaultFramebuffer();
482 }
483 else
484 {
485 if (mSurfacelessFramebuffer == nullptr)
486 {
487 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
488 }
489
490 newDefault = mSurfacelessFramebuffer;
491 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000492
Corentin Wallez37c39792015-08-20 14:19:46 -0400493 // Update default framebuffer, the binding of the previous default
494 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400495 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700496 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400497 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700498 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400499 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700500 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400501 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700502 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400503 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500504 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400505 }
Ian Ewell292f0052016-02-04 10:37:32 -0500506
507 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700508 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000509}
510
Jamie Madill70ee0f62017-02-06 16:04:20 -0500511void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400512{
Corentin Wallez37c39792015-08-20 14:19:46 -0400513 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500514 Framebuffer *currentDefault = nullptr;
515 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400516 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500517 currentDefault = mCurrentSurface->getDefaultFramebuffer();
518 }
519 else if (mSurfacelessFramebuffer != nullptr)
520 {
521 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400522 }
523
Corentin Wallezc295e512017-01-27 17:47:50 -0500524 if (mGLState.getReadFramebuffer() == currentDefault)
525 {
526 mGLState.setReadFramebufferBinding(nullptr);
527 }
528 if (mGLState.getDrawFramebuffer() == currentDefault)
529 {
530 mGLState.setDrawFramebufferBinding(nullptr);
531 }
532 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
533
534 if (mCurrentSurface)
535 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500536 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500537 mCurrentSurface = nullptr;
538 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400539}
540
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000541GLuint Context::createBuffer()
542{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500543 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000544}
545
546GLuint Context::createProgram()
547{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500548 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000549}
550
551GLuint Context::createShader(GLenum type)
552{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500553 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000554}
555
556GLuint Context::createTexture()
557{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500558 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000559}
560
561GLuint Context::createRenderbuffer()
562{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500563 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000564}
565
Geoff Lang882033e2014-09-30 11:26:07 -0400566GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400567{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500568 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400569
Cooper Partind8e62a32015-01-29 15:21:25 -0800570 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400571}
572
Sami Väisänene45e53b2016-05-25 10:36:04 +0300573GLuint Context::createPaths(GLsizei range)
574{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500575 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300576 if (resultOrError.isError())
577 {
578 handleError(resultOrError.getError());
579 return 0;
580 }
581 return resultOrError.getResult();
582}
583
Jamie Madill57a89722013-07-02 11:57:03 -0400584GLuint Context::createVertexArray()
585{
Geoff Lang36167ab2015-12-07 10:27:14 -0500586 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
587 mVertexArrayMap[vertexArray] = nullptr;
588 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400589}
590
Jamie Madilldc356042013-07-19 16:36:57 -0400591GLuint Context::createSampler()
592{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500593 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400594}
595
Geoff Langc8058452014-02-03 12:04:11 -0500596GLuint Context::createTransformFeedback()
597{
Geoff Lang36167ab2015-12-07 10:27:14 -0500598 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
599 mTransformFeedbackMap[transformFeedback] = nullptr;
600 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500601}
602
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603// Returns an unused framebuffer name
604GLuint Context::createFramebuffer()
605{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500606 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000607}
608
Jamie Madill33dc8432013-07-26 11:55:05 -0400609GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000610{
Jamie Madill33dc8432013-07-26 11:55:05 -0400611 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000612
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400613 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000614
615 return handle;
616}
617
618// Returns an unused query name
619GLuint Context::createQuery()
620{
621 GLuint handle = mQueryHandleAllocator.allocate();
622
623 mQueryMap[handle] = NULL;
624
625 return handle;
626}
627
628void Context::deleteBuffer(GLuint buffer)
629{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500630 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631 {
632 detachBuffer(buffer);
633 }
Jamie Madill893ab082014-05-16 16:56:10 -0400634
Jamie Madill6c1f6712017-02-14 19:08:04 -0500635 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000636}
637
638void Context::deleteShader(GLuint shader)
639{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500640 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641}
642
643void Context::deleteProgram(GLuint program)
644{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500645 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000646}
647
648void Context::deleteTexture(GLuint texture)
649{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500650 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651 {
652 detachTexture(texture);
653 }
654
Jamie Madill6c1f6712017-02-14 19:08:04 -0500655 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656}
657
658void Context::deleteRenderbuffer(GLuint renderbuffer)
659{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500660 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000661 {
662 detachRenderbuffer(renderbuffer);
663 }
Jamie Madill893ab082014-05-16 16:56:10 -0400664
Jamie Madill6c1f6712017-02-14 19:08:04 -0500665 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000666}
667
Jamie Madillcd055f82013-07-26 11:55:15 -0400668void Context::deleteFenceSync(GLsync fenceSync)
669{
670 // The spec specifies the underlying Fence object is not deleted until all current
671 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
672 // and since our API is currently designed for being called from a single thread, we can delete
673 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500674 mState.mFenceSyncs->deleteObject(this,
675 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400676}
677
Sami Väisänene45e53b2016-05-25 10:36:04 +0300678void Context::deletePaths(GLuint first, GLsizei range)
679{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500680 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300681}
682
683bool Context::hasPathData(GLuint path) const
684{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500685 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300686 if (pathObj == nullptr)
687 return false;
688
689 return pathObj->hasPathData();
690}
691
692bool Context::hasPath(GLuint path) const
693{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500694 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300695}
696
697void Context::setPathCommands(GLuint path,
698 GLsizei numCommands,
699 const GLubyte *commands,
700 GLsizei numCoords,
701 GLenum coordType,
702 const void *coords)
703{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500704 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300705
706 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
707}
708
709void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
710{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500711 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300712
713 switch (pname)
714 {
715 case GL_PATH_STROKE_WIDTH_CHROMIUM:
716 pathObj->setStrokeWidth(value);
717 break;
718 case GL_PATH_END_CAPS_CHROMIUM:
719 pathObj->setEndCaps(static_cast<GLenum>(value));
720 break;
721 case GL_PATH_JOIN_STYLE_CHROMIUM:
722 pathObj->setJoinStyle(static_cast<GLenum>(value));
723 break;
724 case GL_PATH_MITER_LIMIT_CHROMIUM:
725 pathObj->setMiterLimit(value);
726 break;
727 case GL_PATH_STROKE_BOUND_CHROMIUM:
728 pathObj->setStrokeBound(value);
729 break;
730 default:
731 UNREACHABLE();
732 break;
733 }
734}
735
736void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
737{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500738 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300739
740 switch (pname)
741 {
742 case GL_PATH_STROKE_WIDTH_CHROMIUM:
743 *value = pathObj->getStrokeWidth();
744 break;
745 case GL_PATH_END_CAPS_CHROMIUM:
746 *value = static_cast<GLfloat>(pathObj->getEndCaps());
747 break;
748 case GL_PATH_JOIN_STYLE_CHROMIUM:
749 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
750 break;
751 case GL_PATH_MITER_LIMIT_CHROMIUM:
752 *value = pathObj->getMiterLimit();
753 break;
754 case GL_PATH_STROKE_BOUND_CHROMIUM:
755 *value = pathObj->getStrokeBound();
756 break;
757 default:
758 UNREACHABLE();
759 break;
760 }
761}
762
763void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
764{
765 mGLState.setPathStencilFunc(func, ref, mask);
766}
767
Jamie Madill57a89722013-07-02 11:57:03 -0400768void Context::deleteVertexArray(GLuint vertexArray)
769{
Geoff Lang36167ab2015-12-07 10:27:14 -0500770 auto iter = mVertexArrayMap.find(vertexArray);
771 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000772 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500773 VertexArray *vertexArrayObject = iter->second;
774 if (vertexArrayObject != nullptr)
775 {
776 detachVertexArray(vertexArray);
777 delete vertexArrayObject;
778 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000779
Geoff Lang36167ab2015-12-07 10:27:14 -0500780 mVertexArrayMap.erase(iter);
781 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400782 }
783}
784
Jamie Madilldc356042013-07-19 16:36:57 -0400785void Context::deleteSampler(GLuint sampler)
786{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500787 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400788 {
789 detachSampler(sampler);
790 }
791
Jamie Madill6c1f6712017-02-14 19:08:04 -0500792 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400793}
794
Geoff Langc8058452014-02-03 12:04:11 -0500795void Context::deleteTransformFeedback(GLuint transformFeedback)
796{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500797 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500798 if (iter != mTransformFeedbackMap.end())
799 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500800 TransformFeedback *transformFeedbackObject = iter->second;
801 if (transformFeedbackObject != nullptr)
802 {
803 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500804 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500805 }
806
Geoff Lang50b3fe82015-12-08 14:49:12 +0000807 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500808 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500809 }
810}
811
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000812void Context::deleteFramebuffer(GLuint framebuffer)
813{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500814 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815 {
816 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000817 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500818
Jamie Madill6c1f6712017-02-14 19:08:04 -0500819 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820}
821
Jamie Madill33dc8432013-07-26 11:55:05 -0400822void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000823{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500824 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825
Jamie Madill33dc8432013-07-26 11:55:05 -0400826 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000827 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400828 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000829 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400830 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000831 }
832}
833
834void Context::deleteQuery(GLuint query)
835{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500836 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837 if (queryObject != mQueryMap.end())
838 {
839 mQueryHandleAllocator.release(queryObject->first);
840 if (queryObject->second)
841 {
842 queryObject->second->release();
843 }
844 mQueryMap.erase(queryObject);
845 }
846}
847
Geoff Lang70d0f492015-12-10 17:45:46 -0500848Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500850 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000851}
852
Jamie Madill570f7c82014-07-03 10:38:54 -0400853Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000854{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500855 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000856}
857
Geoff Lang70d0f492015-12-10 17:45:46 -0500858Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000859{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500860 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000861}
862
Jamie Madillcd055f82013-07-26 11:55:15 -0400863FenceSync *Context::getFenceSync(GLsync handle) const
864{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500865 return mState.mFenceSyncs->getFenceSync(
866 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400867}
868
Jamie Madill57a89722013-07-02 11:57:03 -0400869VertexArray *Context::getVertexArray(GLuint handle) const
870{
871 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500872 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400873}
874
Jamie Madilldc356042013-07-19 16:36:57 -0400875Sampler *Context::getSampler(GLuint handle) const
876{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500877 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400878}
879
Geoff Langc8058452014-02-03 12:04:11 -0500880TransformFeedback *Context::getTransformFeedback(GLuint handle) const
881{
Geoff Lang36167ab2015-12-07 10:27:14 -0500882 auto iter = mTransformFeedbackMap.find(handle);
883 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500884}
885
Geoff Lang70d0f492015-12-10 17:45:46 -0500886LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
887{
888 switch (identifier)
889 {
890 case GL_BUFFER:
891 return getBuffer(name);
892 case GL_SHADER:
893 return getShader(name);
894 case GL_PROGRAM:
895 return getProgram(name);
896 case GL_VERTEX_ARRAY:
897 return getVertexArray(name);
898 case GL_QUERY:
899 return getQuery(name);
900 case GL_TRANSFORM_FEEDBACK:
901 return getTransformFeedback(name);
902 case GL_SAMPLER:
903 return getSampler(name);
904 case GL_TEXTURE:
905 return getTexture(name);
906 case GL_RENDERBUFFER:
907 return getRenderbuffer(name);
908 case GL_FRAMEBUFFER:
909 return getFramebuffer(name);
910 default:
911 UNREACHABLE();
912 return nullptr;
913 }
914}
915
916LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
917{
918 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
919}
920
Martin Radev9d901792016-07-15 15:58:58 +0300921void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
922{
923 LabeledObject *object = getLabeledObject(identifier, name);
924 ASSERT(object != nullptr);
925
926 std::string labelName = GetObjectLabelFromPointer(length, label);
927 object->setLabel(labelName);
928}
929
930void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
931{
932 LabeledObject *object = getLabeledObjectFromPtr(ptr);
933 ASSERT(object != nullptr);
934
935 std::string labelName = GetObjectLabelFromPointer(length, label);
936 object->setLabel(labelName);
937}
938
939void Context::getObjectLabel(GLenum identifier,
940 GLuint name,
941 GLsizei bufSize,
942 GLsizei *length,
943 GLchar *label) const
944{
945 LabeledObject *object = getLabeledObject(identifier, name);
946 ASSERT(object != nullptr);
947
948 const std::string &objectLabel = object->getLabel();
949 GetObjectLabelBase(objectLabel, bufSize, length, label);
950}
951
952void Context::getObjectPtrLabel(const void *ptr,
953 GLsizei bufSize,
954 GLsizei *length,
955 GLchar *label) const
956{
957 LabeledObject *object = getLabeledObjectFromPtr(ptr);
958 ASSERT(object != nullptr);
959
960 const std::string &objectLabel = object->getLabel();
961 GetObjectLabelBase(objectLabel, bufSize, length, label);
962}
963
Jamie Madilldc356042013-07-19 16:36:57 -0400964bool Context::isSampler(GLuint samplerName) const
965{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500966 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400967}
968
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500969void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000970{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500971 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700972 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000973}
974
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800975void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
976{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500977 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800978 mGLState.setDrawIndirectBufferBinding(buffer);
979}
980
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500981void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000982{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500983 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700984 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000985}
986
Jamie Madilldedd7b92014-11-05 16:30:36 -0500987void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000988{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500989 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000990
Jamie Madilldedd7b92014-11-05 16:30:36 -0500991 if (handle == 0)
992 {
993 texture = mZeroTextures[target].get();
994 }
995 else
996 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500997 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500998 }
999
1000 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001001 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001002}
1003
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001004void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001005{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001006 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1007 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001008 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001009}
1010
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001011void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001012{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001013 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1014 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001015 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001016}
1017
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001018void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001019{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001020 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001022}
1023
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001025{
Geoff Lang76b10c92014-09-05 16:28:14 -04001026 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001027 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001028 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001029 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001030}
1031
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001032void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001033{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001034 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001035 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001036}
1037
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001038void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1039 GLuint index,
1040 GLintptr offset,
1041 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001042{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001043 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001044 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001045}
1046
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001047void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001048{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001049 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001050 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001051}
1052
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001053void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1054 GLuint index,
1055 GLintptr offset,
1056 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +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.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001060}
1061
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001062void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +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.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001066}
1067
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001068void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001069{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001070 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001071 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001072}
1073
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001074void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001075{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001076 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001077 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001078}
1079
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001080void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001081{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001082 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001083 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001084}
1085
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001086void Context::useProgram(GLuint program)
1087{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001088 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001089}
1090
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001091void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001092{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001093 TransformFeedback *transformFeedback =
1094 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001095 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001096}
1097
Geoff Lang5aad9672014-09-08 11:10:42 -04001098Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001099{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001100 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001101 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001102
Geoff Lang5aad9672014-09-08 11:10:42 -04001103 // begin query
1104 Error error = queryObject->begin();
1105 if (error.isError())
1106 {
1107 return error;
1108 }
1109
1110 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001111 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001112
He Yunchaoacd18982017-01-04 10:46:42 +08001113 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001114}
1115
Geoff Lang5aad9672014-09-08 11:10:42 -04001116Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001117{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001118 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001119 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001120
Geoff Lang5aad9672014-09-08 11:10:42 -04001121 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001122
Geoff Lang5aad9672014-09-08 11:10:42 -04001123 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001124 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001125
1126 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001127}
1128
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001129Error Context::queryCounter(GLuint id, GLenum target)
1130{
1131 ASSERT(target == GL_TIMESTAMP_EXT);
1132
1133 Query *queryObject = getQuery(id, true, target);
1134 ASSERT(queryObject);
1135
1136 return queryObject->queryCounter();
1137}
1138
1139void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1140{
1141 switch (pname)
1142 {
1143 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001144 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001145 break;
1146 case GL_QUERY_COUNTER_BITS_EXT:
1147 switch (target)
1148 {
1149 case GL_TIME_ELAPSED_EXT:
1150 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1151 break;
1152 case GL_TIMESTAMP_EXT:
1153 params[0] = getExtensions().queryCounterBitsTimestamp;
1154 break;
1155 default:
1156 UNREACHABLE();
1157 params[0] = 0;
1158 break;
1159 }
1160 break;
1161 default:
1162 UNREACHABLE();
1163 return;
1164 }
1165}
1166
Geoff Lang2186c382016-10-14 10:54:54 -04001167void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001168{
Geoff Lang2186c382016-10-14 10:54:54 -04001169 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001170}
1171
Geoff Lang2186c382016-10-14 10:54:54 -04001172void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001173{
Geoff Lang2186c382016-10-14 10:54:54 -04001174 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001175}
1176
Geoff Lang2186c382016-10-14 10:54:54 -04001177void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001178{
Geoff Lang2186c382016-10-14 10:54:54 -04001179 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001180}
1181
Geoff Lang2186c382016-10-14 10:54:54 -04001182void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001183{
Geoff Lang2186c382016-10-14 10:54:54 -04001184 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001185}
1186
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001187Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001188{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001189 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001190}
1191
Jamie Madill33dc8432013-07-26 11:55:05 -04001192FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001194 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001195
Jamie Madill33dc8432013-07-26 11:55:05 -04001196 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197 {
1198 return NULL;
1199 }
1200 else
1201 {
1202 return fence->second;
1203 }
1204}
1205
1206Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1207{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001208 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001209
1210 if (query == mQueryMap.end())
1211 {
1212 return NULL;
1213 }
1214 else
1215 {
1216 if (!query->second && create)
1217 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001218 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001219 query->second->addRef();
1220 }
1221 return query->second;
1222 }
1223}
1224
Geoff Lang70d0f492015-12-10 17:45:46 -05001225Query *Context::getQuery(GLuint handle) const
1226{
1227 auto iter = mQueryMap.find(handle);
1228 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1229}
1230
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001231Texture *Context::getTargetTexture(GLenum target) const
1232{
Ian Ewellbda75592016-04-18 17:25:54 -04001233 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001234 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001235}
1236
Geoff Lang76b10c92014-09-05 16:28:14 -04001237Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001239 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240}
1241
Geoff Lang492a7e42014-11-05 13:27:06 -05001242Compiler *Context::getCompiler() const
1243{
1244 return mCompiler;
1245}
1246
Jamie Madill893ab082014-05-16 16:56:10 -04001247void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001248{
1249 switch (pname)
1250 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001251 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001252 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001253 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001254 mGLState.getBooleanv(pname, params);
1255 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001256 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001257}
1258
Jamie Madill893ab082014-05-16 16:56:10 -04001259void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001260{
Shannon Woods53a94a82014-06-24 15:20:36 -04001261 // Queries about context capabilities and maximums are answered by Context.
1262 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263 switch (pname)
1264 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001265 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001266 params[0] = mCaps.minAliasedLineWidth;
1267 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268 break;
1269 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001270 params[0] = mCaps.minAliasedPointSize;
1271 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001273 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001274 ASSERT(mExtensions.textureFilterAnisotropic);
1275 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001276 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001277 case GL_MAX_TEXTURE_LOD_BIAS:
1278 *params = mCaps.maxLODBias;
1279 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001280
1281 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1282 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1283 {
1284 ASSERT(mExtensions.pathRendering);
1285 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1286 memcpy(params, m, 16 * sizeof(GLfloat));
1287 }
1288 break;
1289
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001290 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001291 mGLState.getFloatv(pname, params);
1292 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001293 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001294}
1295
Jamie Madill893ab082014-05-16 16:56:10 -04001296void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001297{
Shannon Woods53a94a82014-06-24 15:20:36 -04001298 // Queries about context capabilities and maximums are answered by Context.
1299 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001300
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001301 switch (pname)
1302 {
Geoff Lang301d1612014-07-09 10:34:37 -04001303 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1304 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1305 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001306 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1307 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1308 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001309 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1310 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1311 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001312 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001313 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1314 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1315 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001316 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001317 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001318 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1319 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1320 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1321 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001322 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1323 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001324 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1325 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001326 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001327 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1328 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1329 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1330 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001331 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001332 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001333 break;
1334 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001335 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001336 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001337 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1338 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001339 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1340 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1341 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001342 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1343 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1344 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001345 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001346 case GL_MAX_VIEWPORT_DIMS:
1347 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001348 params[0] = mCaps.maxViewportWidth;
1349 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001350 }
1351 break;
1352 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001353 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001354 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001355 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1356 *params = mResetStrategy;
1357 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001358 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001359 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001360 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001361 case GL_SHADER_BINARY_FORMATS:
1362 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1363 break;
1364 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001365 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001366 break;
1367 case GL_PROGRAM_BINARY_FORMATS:
1368 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001369 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001370 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001371 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001372 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001373
1374 // GL_KHR_debug
1375 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1376 *params = mExtensions.maxDebugMessageLength;
1377 break;
1378 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1379 *params = mExtensions.maxDebugLoggedMessages;
1380 break;
1381 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1382 *params = mExtensions.maxDebugGroupStackDepth;
1383 break;
1384 case GL_MAX_LABEL_LENGTH:
1385 *params = mExtensions.maxLabelLength;
1386 break;
1387
Ian Ewell53f59f42016-01-28 17:36:55 -05001388 // GL_EXT_disjoint_timer_query
1389 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001390 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001391 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001392 case GL_MAX_FRAMEBUFFER_WIDTH:
1393 *params = mCaps.maxFramebufferWidth;
1394 break;
1395 case GL_MAX_FRAMEBUFFER_HEIGHT:
1396 *params = mCaps.maxFramebufferHeight;
1397 break;
1398 case GL_MAX_FRAMEBUFFER_SAMPLES:
1399 *params = mCaps.maxFramebufferSamples;
1400 break;
1401 case GL_MAX_SAMPLE_MASK_WORDS:
1402 *params = mCaps.maxSampleMaskWords;
1403 break;
1404 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1405 *params = mCaps.maxColorTextureSamples;
1406 break;
1407 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1408 *params = mCaps.maxDepthTextureSamples;
1409 break;
1410 case GL_MAX_INTEGER_SAMPLES:
1411 *params = mCaps.maxIntegerSamples;
1412 break;
1413 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1414 *params = mCaps.maxVertexAttribRelativeOffset;
1415 break;
1416 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1417 *params = mCaps.maxVertexAttribBindings;
1418 break;
1419 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1420 *params = mCaps.maxVertexAttribStride;
1421 break;
1422 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1423 *params = mCaps.maxVertexAtomicCounterBuffers;
1424 break;
1425 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1426 *params = mCaps.maxVertexAtomicCounters;
1427 break;
1428 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1429 *params = mCaps.maxVertexImageUniforms;
1430 break;
1431 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1432 *params = mCaps.maxVertexShaderStorageBlocks;
1433 break;
1434 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1435 *params = mCaps.maxFragmentAtomicCounterBuffers;
1436 break;
1437 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1438 *params = mCaps.maxFragmentAtomicCounters;
1439 break;
1440 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1441 *params = mCaps.maxFragmentImageUniforms;
1442 break;
1443 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1444 *params = mCaps.maxFragmentShaderStorageBlocks;
1445 break;
1446 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1447 *params = mCaps.minProgramTextureGatherOffset;
1448 break;
1449 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1450 *params = mCaps.maxProgramTextureGatherOffset;
1451 break;
1452 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1453 *params = mCaps.maxComputeWorkGroupInvocations;
1454 break;
1455 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1456 *params = mCaps.maxComputeUniformBlocks;
1457 break;
1458 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1459 *params = mCaps.maxComputeTextureImageUnits;
1460 break;
1461 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1462 *params = mCaps.maxComputeSharedMemorySize;
1463 break;
1464 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1465 *params = mCaps.maxComputeUniformComponents;
1466 break;
1467 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1468 *params = mCaps.maxComputeAtomicCounterBuffers;
1469 break;
1470 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1471 *params = mCaps.maxComputeAtomicCounters;
1472 break;
1473 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1474 *params = mCaps.maxComputeImageUniforms;
1475 break;
1476 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1477 *params = mCaps.maxCombinedComputeUniformComponents;
1478 break;
1479 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1480 *params = mCaps.maxComputeShaderStorageBlocks;
1481 break;
1482 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1483 *params = mCaps.maxCombinedShaderOutputResources;
1484 break;
1485 case GL_MAX_UNIFORM_LOCATIONS:
1486 *params = mCaps.maxUniformLocations;
1487 break;
1488 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1489 *params = mCaps.maxAtomicCounterBufferBindings;
1490 break;
1491 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1492 *params = mCaps.maxAtomicCounterBufferSize;
1493 break;
1494 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1495 *params = mCaps.maxCombinedAtomicCounterBuffers;
1496 break;
1497 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1498 *params = mCaps.maxCombinedAtomicCounters;
1499 break;
1500 case GL_MAX_IMAGE_UNITS:
1501 *params = mCaps.maxImageUnits;
1502 break;
1503 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1504 *params = mCaps.maxCombinedImageUniforms;
1505 break;
1506 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1507 *params = mCaps.maxShaderStorageBufferBindings;
1508 break;
1509 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1510 *params = mCaps.maxCombinedShaderStorageBlocks;
1511 break;
1512 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1513 *params = mCaps.shaderStorageBufferOffsetAlignment;
1514 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001515 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001516 mGLState.getIntegerv(mState, pname, params);
1517 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001518 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001519}
1520
Jamie Madill893ab082014-05-16 16:56:10 -04001521void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001522{
Shannon Woods53a94a82014-06-24 15:20:36 -04001523 // Queries about context capabilities and maximums are answered by Context.
1524 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001525 switch (pname)
1526 {
1527 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001528 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001529 break;
1530 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001531 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001532 break;
1533 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001534 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001535 break;
1536 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001537 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001538 break;
1539 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001540 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001541 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001542
1543 // GL_EXT_disjoint_timer_query
1544 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001545 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001546 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001547
1548 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1549 *params = mCaps.maxShaderStorageBlockSize;
1550 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001551 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001552 UNREACHABLE();
1553 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001554 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001555}
1556
Geoff Lang70d0f492015-12-10 17:45:46 -05001557void Context::getPointerv(GLenum pname, void **params) const
1558{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001559 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001560}
1561
Martin Radev66fb8202016-07-28 11:45:20 +03001562void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001563{
Shannon Woods53a94a82014-06-24 15:20:36 -04001564 // Queries about context capabilities and maximums are answered by Context.
1565 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001566
1567 GLenum nativeType;
1568 unsigned int numParams;
1569 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1570 ASSERT(queryStatus);
1571
1572 if (nativeType == GL_INT)
1573 {
1574 switch (target)
1575 {
1576 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1577 ASSERT(index < 3u);
1578 *data = mCaps.maxComputeWorkGroupCount[index];
1579 break;
1580 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1581 ASSERT(index < 3u);
1582 *data = mCaps.maxComputeWorkGroupSize[index];
1583 break;
1584 default:
1585 mGLState.getIntegeri_v(target, index, data);
1586 }
1587 }
1588 else
1589 {
1590 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1591 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001592}
1593
Martin Radev66fb8202016-07-28 11:45:20 +03001594void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001595{
Shannon Woods53a94a82014-06-24 15:20:36 -04001596 // Queries about context capabilities and maximums are answered by Context.
1597 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001598
1599 GLenum nativeType;
1600 unsigned int numParams;
1601 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1602 ASSERT(queryStatus);
1603
1604 if (nativeType == GL_INT_64_ANGLEX)
1605 {
1606 mGLState.getInteger64i_v(target, index, data);
1607 }
1608 else
1609 {
1610 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1611 }
1612}
1613
1614void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1615{
1616 // Queries about context capabilities and maximums are answered by Context.
1617 // Queries about current GL state values are answered by State.
1618
1619 GLenum nativeType;
1620 unsigned int numParams;
1621 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1622 ASSERT(queryStatus);
1623
1624 if (nativeType == GL_BOOL)
1625 {
1626 mGLState.getBooleani_v(target, index, data);
1627 }
1628 else
1629 {
1630 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1631 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001632}
1633
Jamie Madill675fe712016-12-19 13:07:54 -05001634void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001635{
Jamie Madill1b94d432015-08-07 13:23:23 -04001636 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001637 auto error = mImplementation->drawArrays(mode, first, count);
1638 handleError(error);
1639 if (!error.isError())
1640 {
1641 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1642 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001643}
1644
Jamie Madill675fe712016-12-19 13:07:54 -05001645void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001646{
1647 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001648 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1649 handleError(error);
1650 if (!error.isError())
1651 {
1652 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1653 }
Geoff Langf6db0982015-08-25 13:04:00 -04001654}
1655
Jamie Madill675fe712016-12-19 13:07:54 -05001656void Context::drawElements(GLenum mode,
1657 GLsizei count,
1658 GLenum type,
1659 const GLvoid *indices,
1660 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001661{
Jamie Madill1b94d432015-08-07 13:23:23 -04001662 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001663 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001664}
1665
Jamie Madill675fe712016-12-19 13:07:54 -05001666void Context::drawElementsInstanced(GLenum mode,
1667 GLsizei count,
1668 GLenum type,
1669 const GLvoid *indices,
1670 GLsizei instances,
1671 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001672{
1673 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001674 handleError(
1675 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001676}
1677
Jamie Madill675fe712016-12-19 13:07:54 -05001678void Context::drawRangeElements(GLenum mode,
1679 GLuint start,
1680 GLuint end,
1681 GLsizei count,
1682 GLenum type,
1683 const GLvoid *indices,
1684 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001685{
1686 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001687 handleError(
1688 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001689}
1690
Jiajia Qind9671222016-11-29 16:30:31 +08001691void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1692{
1693 syncRendererState();
1694 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1695}
1696
1697void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1698{
1699 syncRendererState();
1700 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1701}
1702
Jamie Madill675fe712016-12-19 13:07:54 -05001703void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001704{
Jamie Madill675fe712016-12-19 13:07:54 -05001705 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001706}
1707
Jamie Madill675fe712016-12-19 13:07:54 -05001708void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001709{
Jamie Madill675fe712016-12-19 13:07:54 -05001710 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001711}
1712
Austin Kinross6ee1e782015-05-29 17:05:37 -07001713void Context::insertEventMarker(GLsizei length, const char *marker)
1714{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001715 ASSERT(mImplementation);
1716 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001717}
1718
1719void Context::pushGroupMarker(GLsizei length, const char *marker)
1720{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001721 ASSERT(mImplementation);
1722 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001723}
1724
1725void Context::popGroupMarker()
1726{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001727 ASSERT(mImplementation);
1728 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001729}
1730
Geoff Langd8605522016-04-13 10:19:12 -04001731void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1732{
1733 Program *programObject = getProgram(program);
1734 ASSERT(programObject);
1735
1736 programObject->bindUniformLocation(location, name);
1737}
1738
Sami Väisänena797e062016-05-12 15:23:40 +03001739void Context::setCoverageModulation(GLenum components)
1740{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001741 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001742}
1743
Sami Väisänene45e53b2016-05-25 10:36:04 +03001744void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1745{
1746 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1747}
1748
1749void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1750{
1751 GLfloat I[16];
1752 angle::Matrix<GLfloat>::setToIdentity(I);
1753
1754 mGLState.loadPathRenderingMatrix(matrixMode, I);
1755}
1756
1757void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1758{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001759 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001760 if (!pathObj)
1761 return;
1762
1763 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1764 syncRendererState();
1765
1766 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1767}
1768
1769void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1770{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001771 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001772 if (!pathObj)
1773 return;
1774
1775 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1776 syncRendererState();
1777
1778 mImplementation->stencilStrokePath(pathObj, reference, mask);
1779}
1780
1781void Context::coverFillPath(GLuint path, GLenum coverMode)
1782{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001783 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001784 if (!pathObj)
1785 return;
1786
1787 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1788 syncRendererState();
1789
1790 mImplementation->coverFillPath(pathObj, coverMode);
1791}
1792
1793void Context::coverStrokePath(GLuint path, GLenum coverMode)
1794{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001795 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001796 if (!pathObj)
1797 return;
1798
1799 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1800 syncRendererState();
1801
1802 mImplementation->coverStrokePath(pathObj, coverMode);
1803}
1804
1805void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1806{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001807 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001808 if (!pathObj)
1809 return;
1810
1811 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1812 syncRendererState();
1813
1814 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1815}
1816
1817void Context::stencilThenCoverStrokePath(GLuint path,
1818 GLint reference,
1819 GLuint mask,
1820 GLenum coverMode)
1821{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001822 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001823 if (!pathObj)
1824 return;
1825
1826 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1827 syncRendererState();
1828
1829 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1830}
1831
Sami Väisänend59ca052016-06-21 16:10:00 +03001832void Context::coverFillPathInstanced(GLsizei numPaths,
1833 GLenum pathNameType,
1834 const void *paths,
1835 GLuint pathBase,
1836 GLenum coverMode,
1837 GLenum transformType,
1838 const GLfloat *transformValues)
1839{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001840 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001841
1842 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1843 syncRendererState();
1844
1845 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1846}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001847
Sami Väisänend59ca052016-06-21 16:10:00 +03001848void Context::coverStrokePathInstanced(GLsizei numPaths,
1849 GLenum pathNameType,
1850 const void *paths,
1851 GLuint pathBase,
1852 GLenum coverMode,
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->coverStrokePathInstanced(pathObjects, coverMode, 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::stencilFillPathInstanced(GLsizei numPaths,
1866 GLenum pathNameType,
1867 const void *paths,
1868 GLuint pathBase,
1869 GLenum fillMode,
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->stencilFillPathInstanced(pathObjects, fillMode, 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::stencilStrokePathInstanced(GLsizei numPaths,
1884 GLenum pathNameType,
1885 const void *paths,
1886 GLuint pathBase,
1887 GLint reference,
1888 GLuint mask,
1889 GLenum transformType,
1890 const GLfloat *transformValues)
1891{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001892 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001893
1894 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1895 syncRendererState();
1896
1897 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1898 transformValues);
1899}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001900
Sami Väisänend59ca052016-06-21 16:10:00 +03001901void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1902 GLenum pathNameType,
1903 const void *paths,
1904 GLuint pathBase,
1905 GLenum fillMode,
1906 GLuint mask,
1907 GLenum coverMode,
1908 GLenum transformType,
1909 const GLfloat *transformValues)
1910{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001911 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001912
1913 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1914 syncRendererState();
1915
1916 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1917 transformType, transformValues);
1918}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001919
Sami Väisänend59ca052016-06-21 16:10:00 +03001920void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1921 GLenum pathNameType,
1922 const void *paths,
1923 GLuint pathBase,
1924 GLint reference,
1925 GLuint mask,
1926 GLenum coverMode,
1927 GLenum transformType,
1928 const GLfloat *transformValues)
1929{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001930 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001931
1932 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1933 syncRendererState();
1934
1935 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1936 transformType, transformValues);
1937}
1938
Sami Väisänen46eaa942016-06-29 10:26:37 +03001939void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1940{
1941 auto *programObject = getProgram(program);
1942
1943 programObject->bindFragmentInputLocation(location, name);
1944}
1945
1946void Context::programPathFragmentInputGen(GLuint program,
1947 GLint location,
1948 GLenum genMode,
1949 GLint components,
1950 const GLfloat *coeffs)
1951{
1952 auto *programObject = getProgram(program);
1953
1954 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1955}
1956
Jamie Madill437fa652016-05-03 15:13:24 -04001957void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001958{
Geoff Langda5777c2014-07-11 09:52:58 -04001959 if (error.isError())
1960 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001961 GLenum code = error.getCode();
1962 mErrors.insert(code);
1963 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1964 {
1965 markContextLost();
1966 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001967
1968 if (!error.getMessage().empty())
1969 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001970 auto *debug = &mGLState.getDebug();
1971 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1972 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001973 }
Geoff Langda5777c2014-07-11 09:52:58 -04001974 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001975}
1976
1977// Get one of the recorded errors and clear its flag, if any.
1978// [OpenGL ES 2.0.24] section 2.5 page 13.
1979GLenum Context::getError()
1980{
Geoff Langda5777c2014-07-11 09:52:58 -04001981 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001982 {
Geoff Langda5777c2014-07-11 09:52:58 -04001983 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001984 }
Geoff Langda5777c2014-07-11 09:52:58 -04001985 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001986 {
Geoff Langda5777c2014-07-11 09:52:58 -04001987 GLenum error = *mErrors.begin();
1988 mErrors.erase(mErrors.begin());
1989 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001990 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001991}
1992
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001993// NOTE: this function should not assume that this context is current!
1994void Context::markContextLost()
1995{
1996 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001997 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001998 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001999 mContextLostForced = true;
2000 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002001 mContextLost = true;
2002}
2003
2004bool Context::isContextLost()
2005{
2006 return mContextLost;
2007}
2008
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002009GLenum Context::getResetStatus()
2010{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002011 // Even if the application doesn't want to know about resets, we want to know
2012 // as it will allow us to skip all the calls.
2013 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002014 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002015 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002016 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002017 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002018 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002019
2020 // EXT_robustness, section 2.6: If the reset notification behavior is
2021 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2022 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2023 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002024 }
2025
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002026 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2027 // status should be returned at least once, and GL_NO_ERROR should be returned
2028 // once the device has finished resetting.
2029 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002030 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002031 ASSERT(mResetStatus == GL_NO_ERROR);
2032 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002033
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002034 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002035 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002036 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002037 }
2038 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002039 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002040 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002041 // If markContextLost was used to mark the context lost then
2042 // assume that is not recoverable, and continue to report the
2043 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002044 mResetStatus = mImplementation->getResetStatus();
2045 }
Jamie Madill893ab082014-05-16 16:56:10 -04002046
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002047 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002048}
2049
2050bool Context::isResetNotificationEnabled()
2051{
2052 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2053}
2054
Corentin Walleze3b10e82015-05-20 11:06:25 -04002055const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002056{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002057 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002058}
2059
2060EGLenum Context::getClientType() const
2061{
2062 return mClientType;
2063}
2064
2065EGLenum Context::getRenderBuffer() const
2066{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002067 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2068 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002069 {
2070 return EGL_NONE;
2071 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002072
2073 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2074 ASSERT(backAttachment != nullptr);
2075 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002076}
2077
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002078VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002079{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002080 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002081 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2082 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002083 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002084 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2085 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002086
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002087 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002088 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002089
2090 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002091}
2092
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002093TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002094{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002095 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002096 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2097 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002098 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002099 transformFeedback =
2100 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002101 transformFeedback->addRef();
2102 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002103 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002104
2105 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002106}
2107
2108bool Context::isVertexArrayGenerated(GLuint vertexArray)
2109{
Geoff Langf41a7152016-09-19 15:11:17 -04002110 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002111 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2112}
2113
2114bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2115{
Geoff Langf41a7152016-09-19 15:11:17 -04002116 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002117 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2118}
2119
Shannon Woods53a94a82014-06-24 15:20:36 -04002120void Context::detachTexture(GLuint texture)
2121{
2122 // Simple pass-through to State's detachTexture method, as textures do not require
2123 // allocation map management either here or in the resource manager at detach time.
2124 // Zero textures are held by the Context, and we don't attempt to request them from
2125 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002126 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002127}
2128
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002129void Context::detachBuffer(GLuint buffer)
2130{
Yuly Novikov5807a532015-12-03 13:01:22 -05002131 // Simple pass-through to State's detachBuffer method, since
2132 // only buffer attachments to container objects that are bound to the current context
2133 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002134
Yuly Novikov5807a532015-12-03 13:01:22 -05002135 // [OpenGL ES 3.2] section 5.1.2 page 45:
2136 // Attachments to unbound container objects, such as
2137 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2138 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002139 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002140}
2141
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002142void Context::detachFramebuffer(GLuint framebuffer)
2143{
Shannon Woods53a94a82014-06-24 15:20:36 -04002144 // Framebuffer detachment is handled by Context, because 0 is a valid
2145 // Framebuffer object, and a pointer to it must be passed from Context
2146 // to State at binding time.
2147
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002148 // [OpenGL ES 2.0.24] section 4.4 page 107:
2149 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2150 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2151
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002152 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002153 {
2154 bindReadFramebuffer(0);
2155 }
2156
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002157 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002158 {
2159 bindDrawFramebuffer(0);
2160 }
2161}
2162
2163void Context::detachRenderbuffer(GLuint renderbuffer)
2164{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002165 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002166}
2167
Jamie Madill57a89722013-07-02 11:57:03 -04002168void Context::detachVertexArray(GLuint vertexArray)
2169{
Jamie Madill77a72f62015-04-14 11:18:32 -04002170 // Vertex array detachment is handled by Context, because 0 is a valid
2171 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002172 // binding time.
2173
Jamie Madill57a89722013-07-02 11:57:03 -04002174 // [OpenGL ES 3.0.2] section 2.10 page 43:
2175 // If a vertex array object that is currently bound is deleted, the binding
2176 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002177 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002178 {
2179 bindVertexArray(0);
2180 }
2181}
2182
Geoff Langc8058452014-02-03 12:04:11 -05002183void Context::detachTransformFeedback(GLuint transformFeedback)
2184{
Corentin Walleza2257da2016-04-19 16:43:12 -04002185 // Transform feedback detachment is handled by Context, because 0 is a valid
2186 // transform feedback, and a pointer to it must be passed from Context to State at
2187 // binding time.
2188
2189 // The OpenGL specification doesn't mention what should happen when the currently bound
2190 // transform feedback object is deleted. Since it is a container object, we treat it like
2191 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002192 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002193 {
2194 bindTransformFeedback(0);
2195 }
Geoff Langc8058452014-02-03 12:04:11 -05002196}
2197
Jamie Madilldc356042013-07-19 16:36:57 -04002198void Context::detachSampler(GLuint sampler)
2199{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002200 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002201}
2202
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002203void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2204{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002205 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002206}
2207
Jamie Madille29d1672013-07-19 16:36:57 -04002208void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2209{
Geoff Langc1984ed2016-10-07 12:41:00 -04002210 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002211 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002212 SetSamplerParameteri(samplerObject, pname, param);
2213}
Jamie Madille29d1672013-07-19 16:36:57 -04002214
Geoff Langc1984ed2016-10-07 12:41:00 -04002215void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2216{
2217 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002218 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002219 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002220}
2221
2222void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2223{
Geoff Langc1984ed2016-10-07 12:41:00 -04002224 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002225 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002226 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002227}
2228
Geoff Langc1984ed2016-10-07 12:41:00 -04002229void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002230{
Geoff Langc1984ed2016-10-07 12:41:00 -04002231 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002232 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002233 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002234}
2235
Geoff Langc1984ed2016-10-07 12:41:00 -04002236void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002237{
Geoff Langc1984ed2016-10-07 12:41:00 -04002238 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002239 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002240 QuerySamplerParameteriv(samplerObject, pname, params);
2241}
Jamie Madill9675b802013-07-19 16:36:59 -04002242
Geoff Langc1984ed2016-10-07 12:41:00 -04002243void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2244{
2245 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002246 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002247 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002248}
2249
Olli Etuahof0fee072016-03-30 15:11:58 +03002250void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2251{
2252 gl::Program *programObject = getProgram(program);
2253 ASSERT(programObject != nullptr);
2254
2255 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2256 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2257}
2258
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002259void Context::initRendererString()
2260{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002261 std::ostringstream rendererString;
2262 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002263 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002264 rendererString << ")";
2265
Geoff Langcec35902014-04-16 10:52:36 -04002266 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002267}
2268
Geoff Langc339c4e2016-11-29 10:37:36 -05002269void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002270{
Geoff Langc339c4e2016-11-29 10:37:36 -05002271 const Version &clientVersion = getClientVersion();
2272
2273 std::ostringstream versionString;
2274 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2275 << ANGLE_VERSION_STRING << ")";
2276 mVersionString = MakeStaticString(versionString.str());
2277
2278 std::ostringstream shadingLanguageVersionString;
2279 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2280 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2281 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2282 << ")";
2283 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002284}
2285
Geoff Langcec35902014-04-16 10:52:36 -04002286void Context::initExtensionStrings()
2287{
Geoff Langc339c4e2016-11-29 10:37:36 -05002288 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2289 std::ostringstream combinedStringStream;
2290 std::copy(strings.begin(), strings.end(),
2291 std::ostream_iterator<const char *>(combinedStringStream, " "));
2292 return MakeStaticString(combinedStringStream.str());
2293 };
2294
2295 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002296 for (const auto &extensionString : mExtensions.getStrings())
2297 {
2298 mExtensionStrings.push_back(MakeStaticString(extensionString));
2299 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002300 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002301
Bryan Bernhart58806562017-01-05 13:09:31 -08002302 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2303
Geoff Langc339c4e2016-11-29 10:37:36 -05002304 mRequestableExtensionStrings.clear();
2305 for (const auto &extensionInfo : GetExtensionInfoMap())
2306 {
2307 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002308 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2309 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002310 {
2311 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2312 }
2313 }
2314 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002315}
2316
Geoff Langc339c4e2016-11-29 10:37:36 -05002317const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002318{
Geoff Langc339c4e2016-11-29 10:37:36 -05002319 switch (name)
2320 {
2321 case GL_VENDOR:
2322 return reinterpret_cast<const GLubyte *>("Google Inc.");
2323
2324 case GL_RENDERER:
2325 return reinterpret_cast<const GLubyte *>(mRendererString);
2326
2327 case GL_VERSION:
2328 return reinterpret_cast<const GLubyte *>(mVersionString);
2329
2330 case GL_SHADING_LANGUAGE_VERSION:
2331 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2332
2333 case GL_EXTENSIONS:
2334 return reinterpret_cast<const GLubyte *>(mExtensionString);
2335
2336 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2337 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2338
2339 default:
2340 UNREACHABLE();
2341 return nullptr;
2342 }
Geoff Langcec35902014-04-16 10:52:36 -04002343}
2344
Geoff Langc339c4e2016-11-29 10:37:36 -05002345const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002346{
Geoff Langc339c4e2016-11-29 10:37:36 -05002347 switch (name)
2348 {
2349 case GL_EXTENSIONS:
2350 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2351
2352 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2353 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2354
2355 default:
2356 UNREACHABLE();
2357 return nullptr;
2358 }
Geoff Langcec35902014-04-16 10:52:36 -04002359}
2360
2361size_t Context::getExtensionStringCount() const
2362{
2363 return mExtensionStrings.size();
2364}
2365
Geoff Langc339c4e2016-11-29 10:37:36 -05002366void Context::requestExtension(const char *name)
2367{
2368 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2369 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2370 const auto &extension = extensionInfos.at(name);
2371 ASSERT(extension.Requestable);
2372
2373 if (mExtensions.*(extension.ExtensionsMember))
2374 {
2375 // Extension already enabled
2376 return;
2377 }
2378
2379 mExtensions.*(extension.ExtensionsMember) = true;
2380 updateCaps();
2381 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002382
2383 // Re-create the compiler with the requested extensions enabled.
2384 SafeDelete(mCompiler);
2385 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002386}
2387
2388size_t Context::getRequestableExtensionStringCount() const
2389{
2390 return mRequestableExtensionStrings.size();
2391}
2392
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002393void Context::beginTransformFeedback(GLenum primitiveMode)
2394{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002395 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002396 ASSERT(transformFeedback != nullptr);
2397 ASSERT(!transformFeedback->isPaused());
2398
Jamie Madill6c1f6712017-02-14 19:08:04 -05002399 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002400}
2401
2402bool Context::hasActiveTransformFeedback(GLuint program) const
2403{
2404 for (auto pair : mTransformFeedbackMap)
2405 {
2406 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2407 {
2408 return true;
2409 }
2410 }
2411 return false;
2412}
2413
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002414void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002415{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002416 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002417
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002418 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002419
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002420 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002421
Geoff Langeb66a6e2016-10-31 13:06:12 -04002422 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002423 {
2424 // Disable ES3+ extensions
2425 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002426 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002427 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002428 }
2429
Geoff Langeb66a6e2016-10-31 13:06:12 -04002430 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002431 {
2432 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2433 //mExtensions.sRGB = false;
2434 }
2435
Jamie Madill00ed7a12016-05-19 13:13:38 -04002436 // Some extensions are always available because they are implemented in the GL layer.
2437 mExtensions.bindUniformLocation = true;
2438 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002439 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002440 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002441 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002442
2443 // Enable the no error extension if the context was created with the flag.
2444 mExtensions.noError = mSkipValidation;
2445
Corentin Wallezccab69d2017-01-27 16:57:15 -05002446 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002447 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002448
Geoff Lang70d0f492015-12-10 17:45:46 -05002449 // Explicitly enable GL_KHR_debug
2450 mExtensions.debug = true;
2451 mExtensions.maxDebugMessageLength = 1024;
2452 mExtensions.maxDebugLoggedMessages = 1024;
2453 mExtensions.maxDebugGroupStackDepth = 1024;
2454 mExtensions.maxLabelLength = 1024;
2455
Geoff Langff5b2d52016-09-07 11:32:23 -04002456 // Explicitly enable GL_ANGLE_robust_client_memory
2457 mExtensions.robustClientMemory = true;
2458
Geoff Lang301d1612014-07-09 10:34:37 -04002459 // Apply implementation limits
2460 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002461 mCaps.maxVertexAttribBindings =
2462 getClientVersion() < ES_3_1
2463 ? mCaps.maxVertexAttributes
2464 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2465
Geoff Lang301d1612014-07-09 10:34:37 -04002466 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2467 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2468
2469 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002470
Geoff Langc287ea62016-09-16 14:46:51 -04002471 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002472 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002473 for (const auto &extensionInfo : GetExtensionInfoMap())
2474 {
2475 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002476 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002477 {
2478 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2479 }
2480 }
2481
2482 // Generate texture caps
2483 updateCaps();
2484}
2485
2486void Context::updateCaps()
2487{
Geoff Lang900013c2014-07-07 11:32:19 -04002488 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002489 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002490
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002491 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002492 {
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002493 GLenum format = capsIt.first;
2494 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002495
Geoff Lang5d601382014-07-22 15:14:06 -04002496 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002497
Geoff Lang0d8b7242015-09-09 14:56:53 -04002498 // Update the format caps based on the client version and extensions.
2499 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2500 // ES3.
2501 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002502 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002503 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002504 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002505 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002506 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002507
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002508 // OpenGL ES does not support multisampling with non-rendererable formats
2509 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2510 if (!formatInfo.renderSupport ||
2511 (getClientVersion() < ES_3_1 &&
2512 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002513 {
Geoff Langd87878e2014-09-19 15:42:59 -04002514 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002515 }
Geoff Langd87878e2014-09-19 15:42:59 -04002516
2517 if (formatCaps.texturable && formatInfo.compressed)
2518 {
2519 mCaps.compressedTextureFormats.push_back(format);
2520 }
2521
2522 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002523 }
2524}
2525
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002526void Context::initWorkarounds()
2527{
2528 // Lose the context upon out of memory error if the application is
2529 // expecting to watch for those events.
2530 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2531}
2532
Jamie Madill1b94d432015-08-07 13:23:23 -04002533void Context::syncRendererState()
2534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002535 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002536 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002537 mGLState.clearDirtyBits();
2538 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002539}
2540
Jamie Madillad9f24e2016-02-12 09:27:24 -05002541void Context::syncRendererState(const State::DirtyBits &bitMask,
2542 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002543{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002544 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002545 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002546 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002547
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002548 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002549}
Jamie Madillc29968b2016-01-20 11:17:23 -05002550
2551void Context::blitFramebuffer(GLint srcX0,
2552 GLint srcY0,
2553 GLint srcX1,
2554 GLint srcY1,
2555 GLint dstX0,
2556 GLint dstY0,
2557 GLint dstX1,
2558 GLint dstY1,
2559 GLbitfield mask,
2560 GLenum filter)
2561{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002562 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002563 ASSERT(drawFramebuffer);
2564
2565 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2566 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2567
Jamie Madillad9f24e2016-02-12 09:27:24 -05002568 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002569
Jamie Madill8415b5f2016-04-26 13:41:39 -04002570 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002571}
Jamie Madillc29968b2016-01-20 11:17:23 -05002572
2573void Context::clear(GLbitfield mask)
2574{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002575 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002576 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002577}
2578
2579void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2580{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002581 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002582 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2583 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002584}
2585
2586void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2587{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002588 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002589 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2590 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002591}
2592
2593void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2594{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002595 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002596 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2597 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002598}
2599
2600void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2601{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002602 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002603 ASSERT(framebufferObject);
2604
2605 // If a buffer is not present, the clear has no effect
2606 if (framebufferObject->getDepthbuffer() == nullptr &&
2607 framebufferObject->getStencilbuffer() == nullptr)
2608 {
2609 return;
2610 }
2611
Jamie Madillad9f24e2016-02-12 09:27:24 -05002612 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002613 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2614 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002615}
2616
2617void Context::readPixels(GLint x,
2618 GLint y,
2619 GLsizei width,
2620 GLsizei height,
2621 GLenum format,
2622 GLenum type,
2623 GLvoid *pixels)
2624{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002625 if (width == 0 || height == 0)
2626 {
2627 return;
2628 }
2629
Jamie Madillad9f24e2016-02-12 09:27:24 -05002630 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002631
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002632 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002633 ASSERT(framebufferObject);
2634
2635 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002636 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002637}
2638
2639void Context::copyTexImage2D(GLenum target,
2640 GLint level,
2641 GLenum internalformat,
2642 GLint x,
2643 GLint y,
2644 GLsizei width,
2645 GLsizei height,
2646 GLint border)
2647{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002648 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002649 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002650
Jamie Madillc29968b2016-01-20 11:17:23 -05002651 Rectangle sourceArea(x, y, width, height);
2652
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002653 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002654 Texture *texture =
2655 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002656 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002657}
2658
2659void Context::copyTexSubImage2D(GLenum target,
2660 GLint level,
2661 GLint xoffset,
2662 GLint yoffset,
2663 GLint x,
2664 GLint y,
2665 GLsizei width,
2666 GLsizei height)
2667{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002668 if (width == 0 || height == 0)
2669 {
2670 return;
2671 }
2672
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002673 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002674 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002675
Jamie Madillc29968b2016-01-20 11:17:23 -05002676 Offset destOffset(xoffset, yoffset, 0);
2677 Rectangle sourceArea(x, y, width, height);
2678
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002679 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002680 Texture *texture =
2681 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002682 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002683}
2684
2685void Context::copyTexSubImage3D(GLenum target,
2686 GLint level,
2687 GLint xoffset,
2688 GLint yoffset,
2689 GLint zoffset,
2690 GLint x,
2691 GLint y,
2692 GLsizei width,
2693 GLsizei height)
2694{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002695 if (width == 0 || height == 0)
2696 {
2697 return;
2698 }
2699
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002700 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002701 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002702
Jamie Madillc29968b2016-01-20 11:17:23 -05002703 Offset destOffset(xoffset, yoffset, zoffset);
2704 Rectangle sourceArea(x, y, width, height);
2705
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002706 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002707 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002708 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002709}
2710
2711void Context::framebufferTexture2D(GLenum target,
2712 GLenum attachment,
2713 GLenum textarget,
2714 GLuint texture,
2715 GLint level)
2716{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002717 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002718 ASSERT(framebuffer);
2719
2720 if (texture != 0)
2721 {
2722 Texture *textureObj = getTexture(texture);
2723
2724 ImageIndex index = ImageIndex::MakeInvalid();
2725
2726 if (textarget == GL_TEXTURE_2D)
2727 {
2728 index = ImageIndex::Make2D(level);
2729 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002730 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2731 {
2732 ASSERT(level == 0);
2733 index = ImageIndex::Make2DMultisample();
2734 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002735 else
2736 {
2737 ASSERT(IsCubeMapTextureTarget(textarget));
2738 index = ImageIndex::MakeCube(textarget, level);
2739 }
2740
2741 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2742 }
2743 else
2744 {
2745 framebuffer->resetAttachment(attachment);
2746 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002747
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002748 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002749}
2750
2751void Context::framebufferRenderbuffer(GLenum target,
2752 GLenum attachment,
2753 GLenum renderbuffertarget,
2754 GLuint renderbuffer)
2755{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002756 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002757 ASSERT(framebuffer);
2758
2759 if (renderbuffer != 0)
2760 {
2761 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2762 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2763 renderbufferObject);
2764 }
2765 else
2766 {
2767 framebuffer->resetAttachment(attachment);
2768 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002769
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002770 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002771}
2772
2773void Context::framebufferTextureLayer(GLenum target,
2774 GLenum attachment,
2775 GLuint texture,
2776 GLint level,
2777 GLint layer)
2778{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002779 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002780 ASSERT(framebuffer);
2781
2782 if (texture != 0)
2783 {
2784 Texture *textureObject = getTexture(texture);
2785
2786 ImageIndex index = ImageIndex::MakeInvalid();
2787
2788 if (textureObject->getTarget() == GL_TEXTURE_3D)
2789 {
2790 index = ImageIndex::Make3D(level, layer);
2791 }
2792 else
2793 {
2794 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2795 index = ImageIndex::Make2DArray(level, layer);
2796 }
2797
2798 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2799 }
2800 else
2801 {
2802 framebuffer->resetAttachment(attachment);
2803 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002804
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002805 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002806}
2807
2808void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2809{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002810 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002811 ASSERT(framebuffer);
2812 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002813 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002814}
2815
2816void Context::readBuffer(GLenum mode)
2817{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002818 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002819 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002820 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002821}
2822
2823void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2824{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002825 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002826 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002827
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002828 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002829 ASSERT(framebuffer);
2830
2831 // The specification isn't clear what should be done when the framebuffer isn't complete.
2832 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002833 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002834}
2835
2836void Context::invalidateFramebuffer(GLenum target,
2837 GLsizei numAttachments,
2838 const GLenum *attachments)
2839{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002840 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002841 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002842
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002843 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002844 ASSERT(framebuffer);
2845
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002846 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002847 {
Jamie Madill437fa652016-05-03 15:13:24 -04002848 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002849 }
Jamie Madill437fa652016-05-03 15:13:24 -04002850
2851 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002852}
2853
2854void Context::invalidateSubFramebuffer(GLenum target,
2855 GLsizei numAttachments,
2856 const GLenum *attachments,
2857 GLint x,
2858 GLint y,
2859 GLsizei width,
2860 GLsizei height)
2861{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002862 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002863 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002864
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002865 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002866 ASSERT(framebuffer);
2867
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002868 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002869 {
Jamie Madill437fa652016-05-03 15:13:24 -04002870 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002871 }
Jamie Madill437fa652016-05-03 15:13:24 -04002872
2873 Rectangle area(x, y, width, height);
2874 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002875}
2876
Jamie Madill73a84962016-02-12 09:27:23 -05002877void Context::texImage2D(GLenum target,
2878 GLint level,
2879 GLint internalformat,
2880 GLsizei width,
2881 GLsizei height,
2882 GLint border,
2883 GLenum format,
2884 GLenum type,
2885 const GLvoid *pixels)
2886{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002887 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002888
2889 Extents size(width, height, 1);
2890 Texture *texture =
2891 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002892 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2893 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002894}
2895
2896void Context::texImage3D(GLenum target,
2897 GLint level,
2898 GLint internalformat,
2899 GLsizei width,
2900 GLsizei height,
2901 GLsizei depth,
2902 GLint border,
2903 GLenum format,
2904 GLenum type,
2905 const GLvoid *pixels)
2906{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002907 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002908
2909 Extents size(width, height, depth);
2910 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002911 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2912 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002913}
2914
2915void Context::texSubImage2D(GLenum target,
2916 GLint level,
2917 GLint xoffset,
2918 GLint yoffset,
2919 GLsizei width,
2920 GLsizei height,
2921 GLenum format,
2922 GLenum type,
2923 const GLvoid *pixels)
2924{
2925 // Zero sized uploads are valid but no-ops
2926 if (width == 0 || height == 0)
2927 {
2928 return;
2929 }
2930
Jamie Madillad9f24e2016-02-12 09:27:24 -05002931 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002932
2933 Box area(xoffset, yoffset, 0, width, height, 1);
2934 Texture *texture =
2935 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002936 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2937 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002938}
2939
2940void Context::texSubImage3D(GLenum target,
2941 GLint level,
2942 GLint xoffset,
2943 GLint yoffset,
2944 GLint zoffset,
2945 GLsizei width,
2946 GLsizei height,
2947 GLsizei depth,
2948 GLenum format,
2949 GLenum type,
2950 const GLvoid *pixels)
2951{
2952 // Zero sized uploads are valid but no-ops
2953 if (width == 0 || height == 0 || depth == 0)
2954 {
2955 return;
2956 }
2957
Jamie Madillad9f24e2016-02-12 09:27:24 -05002958 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002959
2960 Box area(xoffset, yoffset, zoffset, width, height, depth);
2961 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002962 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2963 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002964}
2965
2966void Context::compressedTexImage2D(GLenum target,
2967 GLint level,
2968 GLenum internalformat,
2969 GLsizei width,
2970 GLsizei height,
2971 GLint border,
2972 GLsizei imageSize,
2973 const GLvoid *data)
2974{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002975 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002976
2977 Extents size(width, height, 1);
2978 Texture *texture =
2979 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002980 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002981 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002982 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002983}
2984
2985void Context::compressedTexImage3D(GLenum target,
2986 GLint level,
2987 GLenum internalformat,
2988 GLsizei width,
2989 GLsizei height,
2990 GLsizei depth,
2991 GLint border,
2992 GLsizei imageSize,
2993 const GLvoid *data)
2994{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002995 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002996
2997 Extents size(width, height, depth);
2998 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002999 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003000 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003001 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003002}
3003
3004void Context::compressedTexSubImage2D(GLenum target,
3005 GLint level,
3006 GLint xoffset,
3007 GLint yoffset,
3008 GLsizei width,
3009 GLsizei height,
3010 GLenum format,
3011 GLsizei imageSize,
3012 const GLvoid *data)
3013{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003014 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003015
3016 Box area(xoffset, yoffset, 0, width, height, 1);
3017 Texture *texture =
3018 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003019 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003020 format, imageSize,
3021 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003022}
3023
3024void Context::compressedTexSubImage3D(GLenum target,
3025 GLint level,
3026 GLint xoffset,
3027 GLint yoffset,
3028 GLint zoffset,
3029 GLsizei width,
3030 GLsizei height,
3031 GLsizei depth,
3032 GLenum format,
3033 GLsizei imageSize,
3034 const GLvoid *data)
3035{
3036 // Zero sized uploads are valid but no-ops
3037 if (width == 0 || height == 0)
3038 {
3039 return;
3040 }
3041
Jamie Madillad9f24e2016-02-12 09:27:24 -05003042 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003043
3044 Box area(xoffset, yoffset, zoffset, width, height, depth);
3045 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003046 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003047 format, imageSize,
3048 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003049}
3050
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003051void Context::generateMipmap(GLenum target)
3052{
3053 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003054 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003055}
3056
Geoff Lang97073d12016-04-20 10:42:34 -07003057void Context::copyTextureCHROMIUM(GLuint sourceId,
3058 GLuint destId,
3059 GLint internalFormat,
3060 GLenum destType,
3061 GLboolean unpackFlipY,
3062 GLboolean unpackPremultiplyAlpha,
3063 GLboolean unpackUnmultiplyAlpha)
3064{
3065 syncStateForTexImage();
3066
3067 gl::Texture *sourceTexture = getTexture(sourceId);
3068 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003069 handleError(destTexture->copyTexture(this, internalFormat, destType, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003070 unpackPremultiplyAlpha == GL_TRUE,
3071 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3072}
3073
3074void Context::copySubTextureCHROMIUM(GLuint sourceId,
3075 GLuint destId,
3076 GLint xoffset,
3077 GLint yoffset,
3078 GLint x,
3079 GLint y,
3080 GLsizei width,
3081 GLsizei height,
3082 GLboolean unpackFlipY,
3083 GLboolean unpackPremultiplyAlpha,
3084 GLboolean unpackUnmultiplyAlpha)
3085{
3086 // Zero sized copies are valid but no-ops
3087 if (width == 0 || height == 0)
3088 {
3089 return;
3090 }
3091
3092 syncStateForTexImage();
3093
3094 gl::Texture *sourceTexture = getTexture(sourceId);
3095 gl::Texture *destTexture = getTexture(destId);
3096 Offset offset(xoffset, yoffset, 0);
3097 Rectangle area(x, y, width, height);
Jamie Madill8897afa2017-02-06 17:17:23 -05003098 handleError(destTexture->copySubTexture(this, offset, area, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003099 unpackPremultiplyAlpha == GL_TRUE,
3100 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3101}
3102
Geoff Lang47110bf2016-04-20 11:13:22 -07003103void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3104{
3105 syncStateForTexImage();
3106
3107 gl::Texture *sourceTexture = getTexture(sourceId);
3108 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003109 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003110}
3111
Geoff Lang496c02d2016-10-20 11:38:11 -07003112void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003113{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003114 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003115 ASSERT(buffer);
3116
Geoff Lang496c02d2016-10-20 11:38:11 -07003117 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003118}
3119
3120GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3121{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003122 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003123 ASSERT(buffer);
3124
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003125 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003126 if (error.isError())
3127 {
Jamie Madill437fa652016-05-03 15:13:24 -04003128 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003129 return nullptr;
3130 }
3131
3132 return buffer->getMapPointer();
3133}
3134
3135GLboolean Context::unmapBuffer(GLenum target)
3136{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003137 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003138 ASSERT(buffer);
3139
3140 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003141 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003142 if (error.isError())
3143 {
Jamie Madill437fa652016-05-03 15:13:24 -04003144 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003145 return GL_FALSE;
3146 }
3147
3148 return result;
3149}
3150
3151GLvoid *Context::mapBufferRange(GLenum target,
3152 GLintptr offset,
3153 GLsizeiptr length,
3154 GLbitfield access)
3155{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003156 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003157 ASSERT(buffer);
3158
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003159 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003160 if (error.isError())
3161 {
Jamie Madill437fa652016-05-03 15:13:24 -04003162 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003163 return nullptr;
3164 }
3165
3166 return buffer->getMapPointer();
3167}
3168
3169void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3170{
3171 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3172}
3173
Jamie Madillad9f24e2016-02-12 09:27:24 -05003174void Context::syncStateForReadPixels()
3175{
3176 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3177}
3178
3179void Context::syncStateForTexImage()
3180{
3181 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3182}
3183
3184void Context::syncStateForClear()
3185{
3186 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3187}
3188
3189void Context::syncStateForBlit()
3190{
3191 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3192}
3193
Jamie Madillc20ab272016-06-09 07:20:46 -07003194void Context::activeTexture(GLenum texture)
3195{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003196 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003197}
3198
3199void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3200{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003201 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003202}
3203
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003204void Context::blendEquation(GLenum mode)
3205{
3206 mGLState.setBlendEquation(mode, mode);
3207}
3208
Jamie Madillc20ab272016-06-09 07:20:46 -07003209void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3210{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003211 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003212}
3213
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003214void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3215{
3216 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3217}
3218
Jamie Madillc20ab272016-06-09 07:20:46 -07003219void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3220{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003221 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003222}
3223
3224void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3225{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003226 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003227}
3228
3229void Context::clearDepthf(GLclampf depth)
3230{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003231 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003232}
3233
3234void Context::clearStencil(GLint s)
3235{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003236 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003237}
3238
3239void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3240{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003241 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003242}
3243
3244void Context::cullFace(GLenum mode)
3245{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003246 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003247}
3248
3249void Context::depthFunc(GLenum func)
3250{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003251 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003252}
3253
3254void Context::depthMask(GLboolean flag)
3255{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003256 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003257}
3258
3259void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3260{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003261 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003262}
3263
3264void Context::disable(GLenum cap)
3265{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003266 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003267}
3268
3269void Context::disableVertexAttribArray(GLuint index)
3270{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003271 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003272}
3273
3274void Context::enable(GLenum cap)
3275{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003276 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003277}
3278
3279void Context::enableVertexAttribArray(GLuint index)
3280{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003281 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003282}
3283
3284void Context::frontFace(GLenum mode)
3285{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003286 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003287}
3288
3289void Context::hint(GLenum target, GLenum mode)
3290{
3291 switch (target)
3292 {
3293 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003294 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003295 break;
3296
3297 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003298 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003299 break;
3300
3301 default:
3302 UNREACHABLE();
3303 return;
3304 }
3305}
3306
3307void Context::lineWidth(GLfloat width)
3308{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003309 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003310}
3311
3312void Context::pixelStorei(GLenum pname, GLint param)
3313{
3314 switch (pname)
3315 {
3316 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003317 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003318 break;
3319
3320 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003321 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003322 break;
3323
3324 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003325 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003326 break;
3327
3328 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003329 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003330 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003331 break;
3332
3333 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003334 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003335 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003336 break;
3337
3338 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003339 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003340 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003341 break;
3342
3343 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003344 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003345 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003346 break;
3347
3348 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003349 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003350 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003351 break;
3352
3353 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003354 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003355 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003356 break;
3357
3358 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003359 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003360 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003361 break;
3362
3363 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003364 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003365 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003366 break;
3367
3368 default:
3369 UNREACHABLE();
3370 return;
3371 }
3372}
3373
3374void Context::polygonOffset(GLfloat factor, GLfloat units)
3375{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003376 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003377}
3378
3379void Context::sampleCoverage(GLclampf value, GLboolean invert)
3380{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003381 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003382}
3383
3384void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3385{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003386 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003387}
3388
3389void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3390{
3391 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3392 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003393 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003394 }
3395
3396 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3397 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003398 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003399 }
3400}
3401
3402void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3403{
3404 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3405 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003406 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003407 }
3408
3409 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3410 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003411 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003412 }
3413}
3414
3415void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3416{
3417 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3418 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420 }
3421
3422 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3423 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425 }
3426}
3427
3428void Context::vertexAttrib1f(GLuint index, GLfloat x)
3429{
3430 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003431 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003432}
3433
3434void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3435{
3436 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003437 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003438}
3439
3440void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3441{
3442 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003443 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003444}
3445
3446void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3447{
3448 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003449 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003450}
3451
3452void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3453{
3454 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003455 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003456}
3457
3458void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3459{
3460 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003461 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003462}
3463
3464void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3465{
3466 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003467 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003468}
3469
3470void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3471{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003472 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003473}
3474
3475void Context::vertexAttribPointer(GLuint index,
3476 GLint size,
3477 GLenum type,
3478 GLboolean normalized,
3479 GLsizei stride,
3480 const GLvoid *ptr)
3481{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003482 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3483 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484}
3485
3486void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3487{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003488 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003489}
3490
3491void Context::vertexAttribIPointer(GLuint index,
3492 GLint size,
3493 GLenum type,
3494 GLsizei stride,
3495 const GLvoid *pointer)
3496{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003497 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3498 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003499}
3500
3501void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3502{
3503 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003504 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003505}
3506
3507void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3508{
3509 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003511}
3512
3513void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3514{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003515 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003516}
3517
3518void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3519{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003523void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3524{
3525 const VertexAttribCurrentValueData &currentValues =
3526 getGLState().getVertexAttribCurrentValue(index);
3527 const VertexArray *vao = getGLState().getVertexArray();
3528 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3529 currentValues, pname, params);
3530}
3531
3532void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3533{
3534 const VertexAttribCurrentValueData &currentValues =
3535 getGLState().getVertexAttribCurrentValue(index);
3536 const VertexArray *vao = getGLState().getVertexArray();
3537 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3538 currentValues, pname, params);
3539}
3540
3541void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3542{
3543 const VertexAttribCurrentValueData &currentValues =
3544 getGLState().getVertexAttribCurrentValue(index);
3545 const VertexArray *vao = getGLState().getVertexArray();
3546 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3547 currentValues, pname, params);
3548}
3549
3550void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3551{
3552 const VertexAttribCurrentValueData &currentValues =
3553 getGLState().getVertexAttribCurrentValue(index);
3554 const VertexArray *vao = getGLState().getVertexArray();
3555 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3556 currentValues, pname, params);
3557}
3558
3559void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3560{
3561 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3562 QueryVertexAttribPointerv(attrib, pname, pointer);
3563}
3564
Jamie Madillc20ab272016-06-09 07:20:46 -07003565void Context::debugMessageControl(GLenum source,
3566 GLenum type,
3567 GLenum severity,
3568 GLsizei count,
3569 const GLuint *ids,
3570 GLboolean enabled)
3571{
3572 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003573 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3574 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003575}
3576
3577void Context::debugMessageInsert(GLenum source,
3578 GLenum type,
3579 GLuint id,
3580 GLenum severity,
3581 GLsizei length,
3582 const GLchar *buf)
3583{
3584 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003585 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003586}
3587
3588void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3589{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003590 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003591}
3592
3593GLuint Context::getDebugMessageLog(GLuint count,
3594 GLsizei bufSize,
3595 GLenum *sources,
3596 GLenum *types,
3597 GLuint *ids,
3598 GLenum *severities,
3599 GLsizei *lengths,
3600 GLchar *messageLog)
3601{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003602 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3603 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003604}
3605
3606void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3607{
3608 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003609 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003610}
3611
3612void Context::popDebugGroup()
3613{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003614 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003615}
3616
Jamie Madill29639852016-09-02 15:00:09 -04003617void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3618{
3619 Buffer *buffer = mGLState.getTargetBuffer(target);
3620 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003621 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003622}
3623
3624void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3625{
3626 if (data == nullptr)
3627 {
3628 return;
3629 }
3630
3631 Buffer *buffer = mGLState.getTargetBuffer(target);
3632 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003633 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003634}
3635
Jamie Madillef300b12016-10-07 15:12:09 -04003636void Context::attachShader(GLuint program, GLuint shader)
3637{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003638 auto programObject = mState.mShaderPrograms->getProgram(program);
3639 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003640 ASSERT(programObject && shaderObject);
3641 programObject->attachShader(shaderObject);
3642}
3643
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003644const Workarounds &Context::getWorkarounds() const
3645{
3646 return mWorkarounds;
3647}
3648
Jamie Madillb0817d12016-11-01 15:48:31 -04003649void Context::copyBufferSubData(GLenum readTarget,
3650 GLenum writeTarget,
3651 GLintptr readOffset,
3652 GLintptr writeOffset,
3653 GLsizeiptr size)
3654{
3655 // if size is zero, the copy is a successful no-op
3656 if (size == 0)
3657 {
3658 return;
3659 }
3660
3661 // TODO(jmadill): cache these.
3662 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3663 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3664
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003665 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003666}
3667
Jamie Madill01a80ee2016-11-07 12:06:18 -05003668void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3669{
3670 Program *programObject = getProgram(program);
3671 // TODO(jmadill): Re-use this from the validation if possible.
3672 ASSERT(programObject);
3673 programObject->bindAttributeLocation(index, name);
3674}
3675
3676void Context::bindBuffer(GLenum target, GLuint buffer)
3677{
3678 switch (target)
3679 {
3680 case GL_ARRAY_BUFFER:
3681 bindArrayBuffer(buffer);
3682 break;
3683 case GL_ELEMENT_ARRAY_BUFFER:
3684 bindElementArrayBuffer(buffer);
3685 break;
3686 case GL_COPY_READ_BUFFER:
3687 bindCopyReadBuffer(buffer);
3688 break;
3689 case GL_COPY_WRITE_BUFFER:
3690 bindCopyWriteBuffer(buffer);
3691 break;
3692 case GL_PIXEL_PACK_BUFFER:
3693 bindPixelPackBuffer(buffer);
3694 break;
3695 case GL_PIXEL_UNPACK_BUFFER:
3696 bindPixelUnpackBuffer(buffer);
3697 break;
3698 case GL_UNIFORM_BUFFER:
3699 bindGenericUniformBuffer(buffer);
3700 break;
3701 case GL_TRANSFORM_FEEDBACK_BUFFER:
3702 bindGenericTransformFeedbackBuffer(buffer);
3703 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003704 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003705 if (buffer != 0)
3706 {
3707 // Binding buffers to this binding point is not implemented yet.
3708 UNIMPLEMENTED();
3709 }
Geoff Lang3b573612016-10-31 14:08:10 -04003710 break;
3711 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003712 if (buffer != 0)
3713 {
3714 // Binding buffers to this binding point is not implemented yet.
3715 UNIMPLEMENTED();
3716 }
Geoff Lang3b573612016-10-31 14:08:10 -04003717 break;
3718 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003719 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003720 break;
3721 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003722 if (buffer != 0)
3723 {
3724 // Binding buffers to this binding point is not implemented yet.
3725 UNIMPLEMENTED();
3726 }
Geoff Lang3b573612016-10-31 14:08:10 -04003727 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003728
3729 default:
3730 UNREACHABLE();
3731 break;
3732 }
3733}
3734
3735void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3736{
3737 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3738 {
3739 bindReadFramebuffer(framebuffer);
3740 }
3741
3742 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3743 {
3744 bindDrawFramebuffer(framebuffer);
3745 }
3746}
3747
3748void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3749{
3750 ASSERT(target == GL_RENDERBUFFER);
3751 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003752 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003753 mGLState.setRenderbufferBinding(object);
3754}
3755
JiangYizhoubddc46b2016-12-09 09:50:51 +08003756void Context::texStorage2DMultisample(GLenum target,
3757 GLsizei samples,
3758 GLenum internalformat,
3759 GLsizei width,
3760 GLsizei height,
3761 GLboolean fixedsamplelocations)
3762{
3763 Extents size(width, height, 1);
3764 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003765 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003766 fixedsamplelocations));
3767}
3768
3769void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3770{
3771 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3772 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3773
3774 switch (pname)
3775 {
3776 case GL_SAMPLE_POSITION:
3777 handleError(framebuffer->getSamplePosition(index, val));
3778 break;
3779 default:
3780 UNREACHABLE();
3781 }
3782}
3783
Jamie Madille8fb6402017-02-14 17:56:40 -05003784void Context::renderbufferStorage(GLenum target,
3785 GLenum internalformat,
3786 GLsizei width,
3787 GLsizei height)
3788{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003789 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3790 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3791
Jamie Madille8fb6402017-02-14 17:56:40 -05003792 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003793 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003794}
3795
3796void Context::renderbufferStorageMultisample(GLenum target,
3797 GLsizei samples,
3798 GLenum internalformat,
3799 GLsizei width,
3800 GLsizei height)
3801{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003802 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3803 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05003804
3805 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003806 handleError(
3807 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003808}
3809
JiangYizhoue18e6392017-02-20 10:32:23 +08003810void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
3811{
3812 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3813 QueryFramebufferParameteriv(framebuffer, pname, params);
3814}
3815
3816void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
3817{
3818 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3819 SetFramebufferParameteri(framebuffer, pname, param);
3820}
3821
Jamie Madillc29968b2016-01-20 11:17:23 -05003822} // namespace gl