blob: 4f9936e4b449edcb11a130f57828540eade7964b [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),
269 mSurfacelessFramebuffer(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000270{
Geoff Lang077f20a2016-11-01 10:08:02 -0400271 if (mRobustAccess)
272 {
273 UNIMPLEMENTED();
274 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000275
Corentin Wallezc295e512017-01-27 17:47:50 -0500276 initCaps(GetWebGLContext(attribs), displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700277 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400278
Geoff Langeb66a6e2016-10-31 13:06:12 -0400279 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langfeb8c682017-02-13 16:07:35 -0500280 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100281
Shannon Woods53a94a82014-06-24 15:20:36 -0400282 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400283
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000284 // [OpenGL ES 2.0.24] section 3.7 page 83:
285 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
286 // and cube map texture state vectors respectively associated with them.
287 // In order that access to these initial textures not be lost, they are treated as texture
288 // objects all of whose names are 0.
289
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400290 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500291 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500292
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400293 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500294 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400295
Geoff Langeb66a6e2016-10-31 13:06:12 -0400296 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400297 {
298 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400299 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500300 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400301
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400302 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500303 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400304 }
Geoff Lang3b573612016-10-31 14:08:10 -0400305 if (getClientVersion() >= Version(3, 1))
306 {
307 Texture *zeroTexture2DMultisample =
308 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
309 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
310 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000311
Ian Ewellbda75592016-04-18 17:25:54 -0400312 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
313 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400314 Texture *zeroTextureExternal =
315 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400316 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
317 }
318
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700319 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500320
Jamie Madill57a89722013-07-02 11:57:03 -0400321 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000322 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800323 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000324 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400325
Jamie Madill01a80ee2016-11-07 12:06:18 -0500326 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000327
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000328 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500329 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000330 {
331 bindIndexedUniformBuffer(0, i, 0, -1);
332 }
333
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000334 bindCopyReadBuffer(0);
335 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000336 bindPixelPackBuffer(0);
337 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000338
Geoff Langeb66a6e2016-10-31 13:06:12 -0400339 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400340 {
341 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
342 // In the initial state, a default transform feedback object is bound and treated as
343 // a transform feedback object with a name of zero. That object is bound any time
344 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400345 bindTransformFeedback(0);
346 }
Geoff Langc8058452014-02-03 12:04:11 -0500347
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700348 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500349
350 // Initialize dirty bit masks
351 // TODO(jmadill): additional ES3 state
352 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
353 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
354 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
355 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
356 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
357 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400358 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500359 // No dirty objects.
360
361 // Readpixels uses the pack state and read FBO
362 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
363 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
364 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
365 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
366 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400367 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500368 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
369
370 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
371 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
372 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
373 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
374 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
375 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
376 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
377 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
378 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
379 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
380 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
381 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
382
383 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
384 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700385 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500386 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
387 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400388
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400389 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000390}
391
Jamie Madill70ee0f62017-02-06 16:04:20 -0500392void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000393{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500394 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000395
Corentin Wallez80b24112015-08-25 16:41:57 -0400396 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000397 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400398 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000399 }
400
Corentin Wallez80b24112015-08-25 16:41:57 -0400401 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000402 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400403 if (query.second != nullptr)
404 {
405 query.second->release();
406 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407 }
408
Corentin Wallez80b24112015-08-25 16:41:57 -0400409 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400410 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400411 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400412 }
413
Corentin Wallez80b24112015-08-25 16:41:57 -0400414 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500415 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500416 if (transformFeedback.second != nullptr)
417 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500418 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500419 }
Geoff Langc8058452014-02-03 12:04:11 -0500420 }
421
Jamie Madilldedd7b92014-11-05 16:30:36 -0500422 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400423 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500424 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400425 }
426 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427
Corentin Wallezccab69d2017-01-27 16:57:15 -0500428 SafeDelete(mSurfacelessFramebuffer);
429
Jamie Madill70ee0f62017-02-06 16:04:20 -0500430 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400431
Geoff Lang492a7e42014-11-05 13:27:06 -0500432 SafeDelete(mCompiler);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500433
434 mState.mBuffers->release(this);
435 mState.mShaderPrograms->release(this);
436 mState.mTextures->release(this);
437 mState.mRenderbuffers->release(this);
438 mState.mSamplers->release(this);
439 mState.mFenceSyncs->release(this);
440 mState.mPaths->release(this);
441 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000442}
443
Jamie Madill70ee0f62017-02-06 16:04:20 -0500444Context::~Context()
445{
446}
447
448void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000449{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000450 if (!mHasBeenCurrent)
451 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000452 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500453 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400454 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000455
Corentin Wallezc295e512017-01-27 17:47:50 -0500456 int width = 0;
457 int height = 0;
458 if (surface != nullptr)
459 {
460 width = surface->getWidth();
461 height = surface->getHeight();
462 }
463
464 mGLState.setViewportParams(0, 0, width, height);
465 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000466
467 mHasBeenCurrent = true;
468 }
469
Jamie Madill1b94d432015-08-07 13:23:23 -0400470 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700471 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400472
Jamie Madill70ee0f62017-02-06 16:04:20 -0500473 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500474
475 Framebuffer *newDefault = nullptr;
476 if (surface != nullptr)
477 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500478 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500479 mCurrentSurface = surface;
480 newDefault = surface->getDefaultFramebuffer();
481 }
482 else
483 {
484 if (mSurfacelessFramebuffer == nullptr)
485 {
486 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
487 }
488
489 newDefault = mSurfacelessFramebuffer;
490 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000491
Corentin Wallez37c39792015-08-20 14:19:46 -0400492 // Update default framebuffer, the binding of the previous default
493 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400494 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700495 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400496 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700497 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400498 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700499 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400500 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700501 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400502 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500503 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400504 }
Ian Ewell292f0052016-02-04 10:37:32 -0500505
506 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700507 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000508}
509
Jamie Madill70ee0f62017-02-06 16:04:20 -0500510void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400511{
Corentin Wallez37c39792015-08-20 14:19:46 -0400512 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500513 Framebuffer *currentDefault = nullptr;
514 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400515 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500516 currentDefault = mCurrentSurface->getDefaultFramebuffer();
517 }
518 else if (mSurfacelessFramebuffer != nullptr)
519 {
520 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400521 }
522
Corentin Wallezc295e512017-01-27 17:47:50 -0500523 if (mGLState.getReadFramebuffer() == currentDefault)
524 {
525 mGLState.setReadFramebufferBinding(nullptr);
526 }
527 if (mGLState.getDrawFramebuffer() == currentDefault)
528 {
529 mGLState.setDrawFramebufferBinding(nullptr);
530 }
531 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
532
533 if (mCurrentSurface)
534 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500535 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500536 mCurrentSurface = nullptr;
537 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400538}
539
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000540GLuint Context::createBuffer()
541{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500542 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000543}
544
545GLuint Context::createProgram()
546{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500547 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000548}
549
550GLuint Context::createShader(GLenum type)
551{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500552 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000553}
554
555GLuint Context::createTexture()
556{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500557 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000558}
559
560GLuint Context::createRenderbuffer()
561{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500562 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000563}
564
Geoff Lang882033e2014-09-30 11:26:07 -0400565GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400566{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500567 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400568
Cooper Partind8e62a32015-01-29 15:21:25 -0800569 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400570}
571
Sami Väisänene45e53b2016-05-25 10:36:04 +0300572GLuint Context::createPaths(GLsizei range)
573{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500574 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300575 if (resultOrError.isError())
576 {
577 handleError(resultOrError.getError());
578 return 0;
579 }
580 return resultOrError.getResult();
581}
582
Jamie Madill57a89722013-07-02 11:57:03 -0400583GLuint Context::createVertexArray()
584{
Geoff Lang36167ab2015-12-07 10:27:14 -0500585 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
586 mVertexArrayMap[vertexArray] = nullptr;
587 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400588}
589
Jamie Madilldc356042013-07-19 16:36:57 -0400590GLuint Context::createSampler()
591{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500592 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400593}
594
Geoff Langc8058452014-02-03 12:04:11 -0500595GLuint Context::createTransformFeedback()
596{
Geoff Lang36167ab2015-12-07 10:27:14 -0500597 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
598 mTransformFeedbackMap[transformFeedback] = nullptr;
599 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500600}
601
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000602// Returns an unused framebuffer name
603GLuint Context::createFramebuffer()
604{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500605 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000606}
607
Jamie Madill33dc8432013-07-26 11:55:05 -0400608GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000609{
Jamie Madill33dc8432013-07-26 11:55:05 -0400610 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000611
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400612 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000613
614 return handle;
615}
616
617// Returns an unused query name
618GLuint Context::createQuery()
619{
620 GLuint handle = mQueryHandleAllocator.allocate();
621
622 mQueryMap[handle] = NULL;
623
624 return handle;
625}
626
627void Context::deleteBuffer(GLuint buffer)
628{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500629 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630 {
631 detachBuffer(buffer);
632 }
Jamie Madill893ab082014-05-16 16:56:10 -0400633
Jamie Madill6c1f6712017-02-14 19:08:04 -0500634 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000635}
636
637void Context::deleteShader(GLuint shader)
638{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500639 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000640}
641
642void Context::deleteProgram(GLuint program)
643{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500644 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000645}
646
647void Context::deleteTexture(GLuint texture)
648{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500649 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000650 {
651 detachTexture(texture);
652 }
653
Jamie Madill6c1f6712017-02-14 19:08:04 -0500654 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000655}
656
657void Context::deleteRenderbuffer(GLuint renderbuffer)
658{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500659 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000660 {
661 detachRenderbuffer(renderbuffer);
662 }
Jamie Madill893ab082014-05-16 16:56:10 -0400663
Jamie Madill6c1f6712017-02-14 19:08:04 -0500664 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000665}
666
Jamie Madillcd055f82013-07-26 11:55:15 -0400667void Context::deleteFenceSync(GLsync fenceSync)
668{
669 // The spec specifies the underlying Fence object is not deleted until all current
670 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
671 // and since our API is currently designed for being called from a single thread, we can delete
672 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500673 mState.mFenceSyncs->deleteObject(this,
674 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400675}
676
Sami Väisänene45e53b2016-05-25 10:36:04 +0300677void Context::deletePaths(GLuint first, GLsizei range)
678{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500679 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300680}
681
682bool Context::hasPathData(GLuint path) const
683{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500684 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300685 if (pathObj == nullptr)
686 return false;
687
688 return pathObj->hasPathData();
689}
690
691bool Context::hasPath(GLuint path) const
692{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500693 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300694}
695
696void Context::setPathCommands(GLuint path,
697 GLsizei numCommands,
698 const GLubyte *commands,
699 GLsizei numCoords,
700 GLenum coordType,
701 const void *coords)
702{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500703 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300704
705 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
706}
707
708void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
709{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500710 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300711
712 switch (pname)
713 {
714 case GL_PATH_STROKE_WIDTH_CHROMIUM:
715 pathObj->setStrokeWidth(value);
716 break;
717 case GL_PATH_END_CAPS_CHROMIUM:
718 pathObj->setEndCaps(static_cast<GLenum>(value));
719 break;
720 case GL_PATH_JOIN_STYLE_CHROMIUM:
721 pathObj->setJoinStyle(static_cast<GLenum>(value));
722 break;
723 case GL_PATH_MITER_LIMIT_CHROMIUM:
724 pathObj->setMiterLimit(value);
725 break;
726 case GL_PATH_STROKE_BOUND_CHROMIUM:
727 pathObj->setStrokeBound(value);
728 break;
729 default:
730 UNREACHABLE();
731 break;
732 }
733}
734
735void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
736{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500737 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300738
739 switch (pname)
740 {
741 case GL_PATH_STROKE_WIDTH_CHROMIUM:
742 *value = pathObj->getStrokeWidth();
743 break;
744 case GL_PATH_END_CAPS_CHROMIUM:
745 *value = static_cast<GLfloat>(pathObj->getEndCaps());
746 break;
747 case GL_PATH_JOIN_STYLE_CHROMIUM:
748 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
749 break;
750 case GL_PATH_MITER_LIMIT_CHROMIUM:
751 *value = pathObj->getMiterLimit();
752 break;
753 case GL_PATH_STROKE_BOUND_CHROMIUM:
754 *value = pathObj->getStrokeBound();
755 break;
756 default:
757 UNREACHABLE();
758 break;
759 }
760}
761
762void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
763{
764 mGLState.setPathStencilFunc(func, ref, mask);
765}
766
Jamie Madill57a89722013-07-02 11:57:03 -0400767void Context::deleteVertexArray(GLuint vertexArray)
768{
Geoff Lang36167ab2015-12-07 10:27:14 -0500769 auto iter = mVertexArrayMap.find(vertexArray);
770 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000771 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500772 VertexArray *vertexArrayObject = iter->second;
773 if (vertexArrayObject != nullptr)
774 {
775 detachVertexArray(vertexArray);
776 delete vertexArrayObject;
777 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000778
Geoff Lang36167ab2015-12-07 10:27:14 -0500779 mVertexArrayMap.erase(iter);
780 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400781 }
782}
783
Jamie Madilldc356042013-07-19 16:36:57 -0400784void Context::deleteSampler(GLuint sampler)
785{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500786 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400787 {
788 detachSampler(sampler);
789 }
790
Jamie Madill6c1f6712017-02-14 19:08:04 -0500791 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400792}
793
Geoff Langc8058452014-02-03 12:04:11 -0500794void Context::deleteTransformFeedback(GLuint transformFeedback)
795{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500796 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500797 if (iter != mTransformFeedbackMap.end())
798 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500799 TransformFeedback *transformFeedbackObject = iter->second;
800 if (transformFeedbackObject != nullptr)
801 {
802 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500803 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500804 }
805
Geoff Lang50b3fe82015-12-08 14:49:12 +0000806 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500807 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500808 }
809}
810
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000811void Context::deleteFramebuffer(GLuint framebuffer)
812{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500813 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000814 {
815 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500817
Jamie Madill6c1f6712017-02-14 19:08:04 -0500818 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000819}
820
Jamie Madill33dc8432013-07-26 11:55:05 -0400821void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000822{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500823 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000824
Jamie Madill33dc8432013-07-26 11:55:05 -0400825 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000826 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400827 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000828 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400829 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000830 }
831}
832
833void Context::deleteQuery(GLuint query)
834{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500835 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000836 if (queryObject != mQueryMap.end())
837 {
838 mQueryHandleAllocator.release(queryObject->first);
839 if (queryObject->second)
840 {
841 queryObject->second->release();
842 }
843 mQueryMap.erase(queryObject);
844 }
845}
846
Geoff Lang70d0f492015-12-10 17:45:46 -0500847Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000848{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500849 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850}
851
Jamie Madill570f7c82014-07-03 10:38:54 -0400852Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000853{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500854 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855}
856
Geoff Lang70d0f492015-12-10 17:45:46 -0500857Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000858{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500859 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000860}
861
Jamie Madillcd055f82013-07-26 11:55:15 -0400862FenceSync *Context::getFenceSync(GLsync handle) const
863{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500864 return mState.mFenceSyncs->getFenceSync(
865 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400866}
867
Jamie Madill57a89722013-07-02 11:57:03 -0400868VertexArray *Context::getVertexArray(GLuint handle) const
869{
870 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500871 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400872}
873
Jamie Madilldc356042013-07-19 16:36:57 -0400874Sampler *Context::getSampler(GLuint handle) const
875{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500876 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400877}
878
Geoff Langc8058452014-02-03 12:04:11 -0500879TransformFeedback *Context::getTransformFeedback(GLuint handle) const
880{
Geoff Lang36167ab2015-12-07 10:27:14 -0500881 auto iter = mTransformFeedbackMap.find(handle);
882 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500883}
884
Geoff Lang70d0f492015-12-10 17:45:46 -0500885LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
886{
887 switch (identifier)
888 {
889 case GL_BUFFER:
890 return getBuffer(name);
891 case GL_SHADER:
892 return getShader(name);
893 case GL_PROGRAM:
894 return getProgram(name);
895 case GL_VERTEX_ARRAY:
896 return getVertexArray(name);
897 case GL_QUERY:
898 return getQuery(name);
899 case GL_TRANSFORM_FEEDBACK:
900 return getTransformFeedback(name);
901 case GL_SAMPLER:
902 return getSampler(name);
903 case GL_TEXTURE:
904 return getTexture(name);
905 case GL_RENDERBUFFER:
906 return getRenderbuffer(name);
907 case GL_FRAMEBUFFER:
908 return getFramebuffer(name);
909 default:
910 UNREACHABLE();
911 return nullptr;
912 }
913}
914
915LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
916{
917 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
918}
919
Martin Radev9d901792016-07-15 15:58:58 +0300920void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
921{
922 LabeledObject *object = getLabeledObject(identifier, name);
923 ASSERT(object != nullptr);
924
925 std::string labelName = GetObjectLabelFromPointer(length, label);
926 object->setLabel(labelName);
927}
928
929void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
930{
931 LabeledObject *object = getLabeledObjectFromPtr(ptr);
932 ASSERT(object != nullptr);
933
934 std::string labelName = GetObjectLabelFromPointer(length, label);
935 object->setLabel(labelName);
936}
937
938void Context::getObjectLabel(GLenum identifier,
939 GLuint name,
940 GLsizei bufSize,
941 GLsizei *length,
942 GLchar *label) const
943{
944 LabeledObject *object = getLabeledObject(identifier, name);
945 ASSERT(object != nullptr);
946
947 const std::string &objectLabel = object->getLabel();
948 GetObjectLabelBase(objectLabel, bufSize, length, label);
949}
950
951void Context::getObjectPtrLabel(const void *ptr,
952 GLsizei bufSize,
953 GLsizei *length,
954 GLchar *label) const
955{
956 LabeledObject *object = getLabeledObjectFromPtr(ptr);
957 ASSERT(object != nullptr);
958
959 const std::string &objectLabel = object->getLabel();
960 GetObjectLabelBase(objectLabel, bufSize, length, label);
961}
962
Jamie Madilldc356042013-07-19 16:36:57 -0400963bool Context::isSampler(GLuint samplerName) const
964{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500965 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400966}
967
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500968void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000969{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500970 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700971 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000972}
973
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800974void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
975{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500976 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800977 mGLState.setDrawIndirectBufferBinding(buffer);
978}
979
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500980void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500982 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700983 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984}
985
Jamie Madilldedd7b92014-11-05 16:30:36 -0500986void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500988 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989
Jamie Madilldedd7b92014-11-05 16:30:36 -0500990 if (handle == 0)
991 {
992 texture = mZeroTextures[target].get();
993 }
994 else
995 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500996 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500997 }
998
999 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001000 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001001}
1002
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001003void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001005 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1006 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001007 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001008}
1009
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001010void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001011{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001012 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1013 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001014 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001015}
1016
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001017void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001018{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001019 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001020 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001021}
1022
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001023void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001024{
Geoff Lang76b10c92014-09-05 16:28:14 -04001025 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001026 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001027 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001028 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001029}
1030
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001031void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001032{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001033 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001034 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1038 GLuint index,
1039 GLintptr offset,
1040 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001041{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001042 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001043 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001044}
1045
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001046void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001047{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001048 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001049 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001050}
1051
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001052void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1053 GLuint index,
1054 GLintptr offset,
1055 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001056{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001057 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001058 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001059}
1060
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001061void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001062{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001063 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001064 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001065}
1066
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001067void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001068{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001069 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001070 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001071}
1072
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001073void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001074{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001075 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001076 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001077}
1078
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001079void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001080{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001081 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001082 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001083}
1084
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085void Context::useProgram(GLuint program)
1086{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001087 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001088}
1089
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001090void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001091{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001092 TransformFeedback *transformFeedback =
1093 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001094 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001095}
1096
Geoff Lang5aad9672014-09-08 11:10:42 -04001097Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001098{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001099 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001100 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001101
Geoff Lang5aad9672014-09-08 11:10:42 -04001102 // begin query
1103 Error error = queryObject->begin();
1104 if (error.isError())
1105 {
1106 return error;
1107 }
1108
1109 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001110 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001111
He Yunchaoacd18982017-01-04 10:46:42 +08001112 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001113}
1114
Geoff Lang5aad9672014-09-08 11:10:42 -04001115Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001116{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001117 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001118 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001119
Geoff Lang5aad9672014-09-08 11:10:42 -04001120 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001121
Geoff Lang5aad9672014-09-08 11:10:42 -04001122 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001123 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001124
1125 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001126}
1127
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001128Error Context::queryCounter(GLuint id, GLenum target)
1129{
1130 ASSERT(target == GL_TIMESTAMP_EXT);
1131
1132 Query *queryObject = getQuery(id, true, target);
1133 ASSERT(queryObject);
1134
1135 return queryObject->queryCounter();
1136}
1137
1138void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1139{
1140 switch (pname)
1141 {
1142 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001143 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001144 break;
1145 case GL_QUERY_COUNTER_BITS_EXT:
1146 switch (target)
1147 {
1148 case GL_TIME_ELAPSED_EXT:
1149 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1150 break;
1151 case GL_TIMESTAMP_EXT:
1152 params[0] = getExtensions().queryCounterBitsTimestamp;
1153 break;
1154 default:
1155 UNREACHABLE();
1156 params[0] = 0;
1157 break;
1158 }
1159 break;
1160 default:
1161 UNREACHABLE();
1162 return;
1163 }
1164}
1165
Geoff Lang2186c382016-10-14 10:54:54 -04001166void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001167{
Geoff Lang2186c382016-10-14 10:54:54 -04001168 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001169}
1170
Geoff Lang2186c382016-10-14 10:54:54 -04001171void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001172{
Geoff Lang2186c382016-10-14 10:54:54 -04001173 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001174}
1175
Geoff Lang2186c382016-10-14 10:54:54 -04001176void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001177{
Geoff Lang2186c382016-10-14 10:54:54 -04001178 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001179}
1180
Geoff Lang2186c382016-10-14 10:54:54 -04001181void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001182{
Geoff Lang2186c382016-10-14 10:54:54 -04001183 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001184}
1185
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001186Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001188 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189}
1190
Jamie Madill33dc8432013-07-26 11:55:05 -04001191FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001192{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001193 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001194
Jamie Madill33dc8432013-07-26 11:55:05 -04001195 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001196 {
1197 return NULL;
1198 }
1199 else
1200 {
1201 return fence->second;
1202 }
1203}
1204
1205Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1206{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001207 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001208
1209 if (query == mQueryMap.end())
1210 {
1211 return NULL;
1212 }
1213 else
1214 {
1215 if (!query->second && create)
1216 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001217 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218 query->second->addRef();
1219 }
1220 return query->second;
1221 }
1222}
1223
Geoff Lang70d0f492015-12-10 17:45:46 -05001224Query *Context::getQuery(GLuint handle) const
1225{
1226 auto iter = mQueryMap.find(handle);
1227 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1228}
1229
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001230Texture *Context::getTargetTexture(GLenum target) const
1231{
Ian Ewellbda75592016-04-18 17:25:54 -04001232 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001233 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001234}
1235
Geoff Lang76b10c92014-09-05 16:28:14 -04001236Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001238 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001239}
1240
Geoff Lang492a7e42014-11-05 13:27:06 -05001241Compiler *Context::getCompiler() const
1242{
1243 return mCompiler;
1244}
1245
Jamie Madill893ab082014-05-16 16:56:10 -04001246void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001247{
1248 switch (pname)
1249 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001250 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001251 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001252 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001253 mGLState.getBooleanv(pname, params);
1254 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001256}
1257
Jamie Madill893ab082014-05-16 16:56:10 -04001258void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001259{
Shannon Woods53a94a82014-06-24 15:20:36 -04001260 // Queries about context capabilities and maximums are answered by Context.
1261 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262 switch (pname)
1263 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001264 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001265 params[0] = mCaps.minAliasedLineWidth;
1266 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267 break;
1268 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001269 params[0] = mCaps.minAliasedPointSize;
1270 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001272 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001273 ASSERT(mExtensions.textureFilterAnisotropic);
1274 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001275 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001276 case GL_MAX_TEXTURE_LOD_BIAS:
1277 *params = mCaps.maxLODBias;
1278 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001279
1280 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1281 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1282 {
1283 ASSERT(mExtensions.pathRendering);
1284 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1285 memcpy(params, m, 16 * sizeof(GLfloat));
1286 }
1287 break;
1288
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001289 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001290 mGLState.getFloatv(pname, params);
1291 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001292 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001293}
1294
Jamie Madill893ab082014-05-16 16:56:10 -04001295void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001296{
Shannon Woods53a94a82014-06-24 15:20:36 -04001297 // Queries about context capabilities and maximums are answered by Context.
1298 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001299
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001300 switch (pname)
1301 {
Geoff Lang301d1612014-07-09 10:34:37 -04001302 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1303 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1304 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001305 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1306 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1307 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001308 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1309 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1310 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001311 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001312 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1313 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1314 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001315 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001316 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001317 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1318 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1319 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1320 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001321 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1322 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001323 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1324 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001325 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001326 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1327 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1328 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1329 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001330 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001331 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001332 break;
1333 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001334 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001335 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001336 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1337 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001338 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1339 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1340 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001341 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1342 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1343 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001344 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001345 case GL_MAX_VIEWPORT_DIMS:
1346 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001347 params[0] = mCaps.maxViewportWidth;
1348 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001349 }
1350 break;
1351 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001352 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001353 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001354 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1355 *params = mResetStrategy;
1356 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001357 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001358 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001359 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001360 case GL_SHADER_BINARY_FORMATS:
1361 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1362 break;
1363 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001364 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001365 break;
1366 case GL_PROGRAM_BINARY_FORMATS:
1367 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001368 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001369 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001370 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001371 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001372
1373 // GL_KHR_debug
1374 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1375 *params = mExtensions.maxDebugMessageLength;
1376 break;
1377 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1378 *params = mExtensions.maxDebugLoggedMessages;
1379 break;
1380 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1381 *params = mExtensions.maxDebugGroupStackDepth;
1382 break;
1383 case GL_MAX_LABEL_LENGTH:
1384 *params = mExtensions.maxLabelLength;
1385 break;
1386
Ian Ewell53f59f42016-01-28 17:36:55 -05001387 // GL_EXT_disjoint_timer_query
1388 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001389 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001390 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001391 case GL_MAX_FRAMEBUFFER_WIDTH:
1392 *params = mCaps.maxFramebufferWidth;
1393 break;
1394 case GL_MAX_FRAMEBUFFER_HEIGHT:
1395 *params = mCaps.maxFramebufferHeight;
1396 break;
1397 case GL_MAX_FRAMEBUFFER_SAMPLES:
1398 *params = mCaps.maxFramebufferSamples;
1399 break;
1400 case GL_MAX_SAMPLE_MASK_WORDS:
1401 *params = mCaps.maxSampleMaskWords;
1402 break;
1403 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1404 *params = mCaps.maxColorTextureSamples;
1405 break;
1406 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1407 *params = mCaps.maxDepthTextureSamples;
1408 break;
1409 case GL_MAX_INTEGER_SAMPLES:
1410 *params = mCaps.maxIntegerSamples;
1411 break;
1412 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1413 *params = mCaps.maxVertexAttribRelativeOffset;
1414 break;
1415 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1416 *params = mCaps.maxVertexAttribBindings;
1417 break;
1418 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1419 *params = mCaps.maxVertexAttribStride;
1420 break;
1421 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1422 *params = mCaps.maxVertexAtomicCounterBuffers;
1423 break;
1424 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1425 *params = mCaps.maxVertexAtomicCounters;
1426 break;
1427 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1428 *params = mCaps.maxVertexImageUniforms;
1429 break;
1430 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1431 *params = mCaps.maxVertexShaderStorageBlocks;
1432 break;
1433 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1434 *params = mCaps.maxFragmentAtomicCounterBuffers;
1435 break;
1436 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1437 *params = mCaps.maxFragmentAtomicCounters;
1438 break;
1439 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1440 *params = mCaps.maxFragmentImageUniforms;
1441 break;
1442 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1443 *params = mCaps.maxFragmentShaderStorageBlocks;
1444 break;
1445 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1446 *params = mCaps.minProgramTextureGatherOffset;
1447 break;
1448 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1449 *params = mCaps.maxProgramTextureGatherOffset;
1450 break;
1451 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1452 *params = mCaps.maxComputeWorkGroupInvocations;
1453 break;
1454 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1455 *params = mCaps.maxComputeUniformBlocks;
1456 break;
1457 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1458 *params = mCaps.maxComputeTextureImageUnits;
1459 break;
1460 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1461 *params = mCaps.maxComputeSharedMemorySize;
1462 break;
1463 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1464 *params = mCaps.maxComputeUniformComponents;
1465 break;
1466 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1467 *params = mCaps.maxComputeAtomicCounterBuffers;
1468 break;
1469 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1470 *params = mCaps.maxComputeAtomicCounters;
1471 break;
1472 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1473 *params = mCaps.maxComputeImageUniforms;
1474 break;
1475 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1476 *params = mCaps.maxCombinedComputeUniformComponents;
1477 break;
1478 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1479 *params = mCaps.maxComputeShaderStorageBlocks;
1480 break;
1481 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1482 *params = mCaps.maxCombinedShaderOutputResources;
1483 break;
1484 case GL_MAX_UNIFORM_LOCATIONS:
1485 *params = mCaps.maxUniformLocations;
1486 break;
1487 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1488 *params = mCaps.maxAtomicCounterBufferBindings;
1489 break;
1490 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1491 *params = mCaps.maxAtomicCounterBufferSize;
1492 break;
1493 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1494 *params = mCaps.maxCombinedAtomicCounterBuffers;
1495 break;
1496 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1497 *params = mCaps.maxCombinedAtomicCounters;
1498 break;
1499 case GL_MAX_IMAGE_UNITS:
1500 *params = mCaps.maxImageUnits;
1501 break;
1502 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1503 *params = mCaps.maxCombinedImageUniforms;
1504 break;
1505 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1506 *params = mCaps.maxShaderStorageBufferBindings;
1507 break;
1508 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1509 *params = mCaps.maxCombinedShaderStorageBlocks;
1510 break;
1511 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1512 *params = mCaps.shaderStorageBufferOffsetAlignment;
1513 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001514 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001515 mGLState.getIntegerv(mState, pname, params);
1516 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001517 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001518}
1519
Jamie Madill893ab082014-05-16 16:56:10 -04001520void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001521{
Shannon Woods53a94a82014-06-24 15:20:36 -04001522 // Queries about context capabilities and maximums are answered by Context.
1523 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001524 switch (pname)
1525 {
1526 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001527 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001528 break;
1529 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001530 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001531 break;
1532 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001533 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001534 break;
1535 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001536 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001537 break;
1538 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001539 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001540 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001541
1542 // GL_EXT_disjoint_timer_query
1543 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001544 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001545 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001546
1547 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1548 *params = mCaps.maxShaderStorageBlockSize;
1549 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001550 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001551 UNREACHABLE();
1552 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001553 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001554}
1555
Geoff Lang70d0f492015-12-10 17:45:46 -05001556void Context::getPointerv(GLenum pname, void **params) const
1557{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001558 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001559}
1560
Martin Radev66fb8202016-07-28 11:45:20 +03001561void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001562{
Shannon Woods53a94a82014-06-24 15:20:36 -04001563 // Queries about context capabilities and maximums are answered by Context.
1564 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001565
1566 GLenum nativeType;
1567 unsigned int numParams;
1568 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1569 ASSERT(queryStatus);
1570
1571 if (nativeType == GL_INT)
1572 {
1573 switch (target)
1574 {
1575 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1576 ASSERT(index < 3u);
1577 *data = mCaps.maxComputeWorkGroupCount[index];
1578 break;
1579 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1580 ASSERT(index < 3u);
1581 *data = mCaps.maxComputeWorkGroupSize[index];
1582 break;
1583 default:
1584 mGLState.getIntegeri_v(target, index, data);
1585 }
1586 }
1587 else
1588 {
1589 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1590 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001591}
1592
Martin Radev66fb8202016-07-28 11:45:20 +03001593void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001594{
Shannon Woods53a94a82014-06-24 15:20:36 -04001595 // Queries about context capabilities and maximums are answered by Context.
1596 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001597
1598 GLenum nativeType;
1599 unsigned int numParams;
1600 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1601 ASSERT(queryStatus);
1602
1603 if (nativeType == GL_INT_64_ANGLEX)
1604 {
1605 mGLState.getInteger64i_v(target, index, data);
1606 }
1607 else
1608 {
1609 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1610 }
1611}
1612
1613void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1614{
1615 // Queries about context capabilities and maximums are answered by Context.
1616 // Queries about current GL state values are answered by State.
1617
1618 GLenum nativeType;
1619 unsigned int numParams;
1620 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1621 ASSERT(queryStatus);
1622
1623 if (nativeType == GL_BOOL)
1624 {
1625 mGLState.getBooleani_v(target, index, data);
1626 }
1627 else
1628 {
1629 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1630 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001631}
1632
Jamie Madill675fe712016-12-19 13:07:54 -05001633void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001634{
Jamie Madill1b94d432015-08-07 13:23:23 -04001635 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001636 auto error = mImplementation->drawArrays(mode, first, count);
1637 handleError(error);
1638 if (!error.isError())
1639 {
1640 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1641 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001642}
1643
Jamie Madill675fe712016-12-19 13:07:54 -05001644void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001645{
1646 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001647 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1648 handleError(error);
1649 if (!error.isError())
1650 {
1651 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1652 }
Geoff Langf6db0982015-08-25 13:04:00 -04001653}
1654
Jamie Madill675fe712016-12-19 13:07:54 -05001655void Context::drawElements(GLenum mode,
1656 GLsizei count,
1657 GLenum type,
1658 const GLvoid *indices,
1659 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001660{
Jamie Madill1b94d432015-08-07 13:23:23 -04001661 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001662 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001663}
1664
Jamie Madill675fe712016-12-19 13:07:54 -05001665void Context::drawElementsInstanced(GLenum mode,
1666 GLsizei count,
1667 GLenum type,
1668 const GLvoid *indices,
1669 GLsizei instances,
1670 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001671{
1672 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001673 handleError(
1674 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001675}
1676
Jamie Madill675fe712016-12-19 13:07:54 -05001677void Context::drawRangeElements(GLenum mode,
1678 GLuint start,
1679 GLuint end,
1680 GLsizei count,
1681 GLenum type,
1682 const GLvoid *indices,
1683 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001684{
1685 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001686 handleError(
1687 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001688}
1689
Jiajia Qind9671222016-11-29 16:30:31 +08001690void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1691{
1692 syncRendererState();
1693 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1694}
1695
1696void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1697{
1698 syncRendererState();
1699 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1700}
1701
Jamie Madill675fe712016-12-19 13:07:54 -05001702void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001703{
Jamie Madill675fe712016-12-19 13:07:54 -05001704 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001705}
1706
Jamie Madill675fe712016-12-19 13:07:54 -05001707void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001708{
Jamie Madill675fe712016-12-19 13:07:54 -05001709 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001710}
1711
Austin Kinross6ee1e782015-05-29 17:05:37 -07001712void Context::insertEventMarker(GLsizei length, const char *marker)
1713{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001714 ASSERT(mImplementation);
1715 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001716}
1717
1718void Context::pushGroupMarker(GLsizei length, const char *marker)
1719{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001720 ASSERT(mImplementation);
1721 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001722}
1723
1724void Context::popGroupMarker()
1725{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001726 ASSERT(mImplementation);
1727 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001728}
1729
Geoff Langd8605522016-04-13 10:19:12 -04001730void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1731{
1732 Program *programObject = getProgram(program);
1733 ASSERT(programObject);
1734
1735 programObject->bindUniformLocation(location, name);
1736}
1737
Sami Väisänena797e062016-05-12 15:23:40 +03001738void Context::setCoverageModulation(GLenum components)
1739{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001740 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001741}
1742
Sami Väisänene45e53b2016-05-25 10:36:04 +03001743void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1744{
1745 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1746}
1747
1748void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1749{
1750 GLfloat I[16];
1751 angle::Matrix<GLfloat>::setToIdentity(I);
1752
1753 mGLState.loadPathRenderingMatrix(matrixMode, I);
1754}
1755
1756void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1757{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001758 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001759 if (!pathObj)
1760 return;
1761
1762 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1763 syncRendererState();
1764
1765 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1766}
1767
1768void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1769{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001770 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001771 if (!pathObj)
1772 return;
1773
1774 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1775 syncRendererState();
1776
1777 mImplementation->stencilStrokePath(pathObj, reference, mask);
1778}
1779
1780void Context::coverFillPath(GLuint path, GLenum coverMode)
1781{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001782 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001783 if (!pathObj)
1784 return;
1785
1786 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1787 syncRendererState();
1788
1789 mImplementation->coverFillPath(pathObj, coverMode);
1790}
1791
1792void Context::coverStrokePath(GLuint path, GLenum coverMode)
1793{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001794 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001795 if (!pathObj)
1796 return;
1797
1798 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1799 syncRendererState();
1800
1801 mImplementation->coverStrokePath(pathObj, coverMode);
1802}
1803
1804void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1805{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001806 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001807 if (!pathObj)
1808 return;
1809
1810 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1811 syncRendererState();
1812
1813 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1814}
1815
1816void Context::stencilThenCoverStrokePath(GLuint path,
1817 GLint reference,
1818 GLuint mask,
1819 GLenum coverMode)
1820{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001821 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001822 if (!pathObj)
1823 return;
1824
1825 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1826 syncRendererState();
1827
1828 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1829}
1830
Sami Väisänend59ca052016-06-21 16:10:00 +03001831void Context::coverFillPathInstanced(GLsizei numPaths,
1832 GLenum pathNameType,
1833 const void *paths,
1834 GLuint pathBase,
1835 GLenum coverMode,
1836 GLenum transformType,
1837 const GLfloat *transformValues)
1838{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001839 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001840
1841 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1842 syncRendererState();
1843
1844 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1845}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001846
Sami Väisänend59ca052016-06-21 16:10:00 +03001847void Context::coverStrokePathInstanced(GLsizei numPaths,
1848 GLenum pathNameType,
1849 const void *paths,
1850 GLuint pathBase,
1851 GLenum coverMode,
1852 GLenum transformType,
1853 const GLfloat *transformValues)
1854{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001855 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001856
1857 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1858 syncRendererState();
1859
1860 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1861 transformValues);
1862}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001863
Sami Väisänend59ca052016-06-21 16:10:00 +03001864void Context::stencilFillPathInstanced(GLsizei numPaths,
1865 GLenum pathNameType,
1866 const void *paths,
1867 GLuint pathBase,
1868 GLenum fillMode,
1869 GLuint mask,
1870 GLenum transformType,
1871 const GLfloat *transformValues)
1872{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001873 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001874
1875 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1876 syncRendererState();
1877
1878 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1879 transformValues);
1880}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001881
Sami Väisänend59ca052016-06-21 16:10:00 +03001882void Context::stencilStrokePathInstanced(GLsizei numPaths,
1883 GLenum pathNameType,
1884 const void *paths,
1885 GLuint pathBase,
1886 GLint reference,
1887 GLuint mask,
1888 GLenum transformType,
1889 const GLfloat *transformValues)
1890{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001891 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001892
1893 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1894 syncRendererState();
1895
1896 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1897 transformValues);
1898}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001899
Sami Väisänend59ca052016-06-21 16:10:00 +03001900void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1901 GLenum pathNameType,
1902 const void *paths,
1903 GLuint pathBase,
1904 GLenum fillMode,
1905 GLuint mask,
1906 GLenum coverMode,
1907 GLenum transformType,
1908 const GLfloat *transformValues)
1909{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001910 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001911
1912 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1913 syncRendererState();
1914
1915 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1916 transformType, transformValues);
1917}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001918
Sami Väisänend59ca052016-06-21 16:10:00 +03001919void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1920 GLenum pathNameType,
1921 const void *paths,
1922 GLuint pathBase,
1923 GLint reference,
1924 GLuint mask,
1925 GLenum coverMode,
1926 GLenum transformType,
1927 const GLfloat *transformValues)
1928{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001929 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001930
1931 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1932 syncRendererState();
1933
1934 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1935 transformType, transformValues);
1936}
1937
Sami Väisänen46eaa942016-06-29 10:26:37 +03001938void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1939{
1940 auto *programObject = getProgram(program);
1941
1942 programObject->bindFragmentInputLocation(location, name);
1943}
1944
1945void Context::programPathFragmentInputGen(GLuint program,
1946 GLint location,
1947 GLenum genMode,
1948 GLint components,
1949 const GLfloat *coeffs)
1950{
1951 auto *programObject = getProgram(program);
1952
1953 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1954}
1955
Jamie Madill437fa652016-05-03 15:13:24 -04001956void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001957{
Geoff Langda5777c2014-07-11 09:52:58 -04001958 if (error.isError())
1959 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001960 GLenum code = error.getCode();
1961 mErrors.insert(code);
1962 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1963 {
1964 markContextLost();
1965 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001966
1967 if (!error.getMessage().empty())
1968 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001969 auto *debug = &mGLState.getDebug();
1970 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1971 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001972 }
Geoff Langda5777c2014-07-11 09:52:58 -04001973 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001974}
1975
1976// Get one of the recorded errors and clear its flag, if any.
1977// [OpenGL ES 2.0.24] section 2.5 page 13.
1978GLenum Context::getError()
1979{
Geoff Langda5777c2014-07-11 09:52:58 -04001980 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001981 {
Geoff Langda5777c2014-07-11 09:52:58 -04001982 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001983 }
Geoff Langda5777c2014-07-11 09:52:58 -04001984 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001985 {
Geoff Langda5777c2014-07-11 09:52:58 -04001986 GLenum error = *mErrors.begin();
1987 mErrors.erase(mErrors.begin());
1988 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001989 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001990}
1991
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001992// NOTE: this function should not assume that this context is current!
1993void Context::markContextLost()
1994{
1995 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001996 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001997 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001998 mContextLostForced = true;
1999 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002000 mContextLost = true;
2001}
2002
2003bool Context::isContextLost()
2004{
2005 return mContextLost;
2006}
2007
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002008GLenum Context::getResetStatus()
2009{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002010 // Even if the application doesn't want to know about resets, we want to know
2011 // as it will allow us to skip all the calls.
2012 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002013 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002014 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002015 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002016 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002017 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002018
2019 // EXT_robustness, section 2.6: If the reset notification behavior is
2020 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2021 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2022 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002023 }
2024
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002025 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2026 // status should be returned at least once, and GL_NO_ERROR should be returned
2027 // once the device has finished resetting.
2028 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002029 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002030 ASSERT(mResetStatus == GL_NO_ERROR);
2031 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002032
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002033 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002034 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002035 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002036 }
2037 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002038 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002039 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002040 // If markContextLost was used to mark the context lost then
2041 // assume that is not recoverable, and continue to report the
2042 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002043 mResetStatus = mImplementation->getResetStatus();
2044 }
Jamie Madill893ab082014-05-16 16:56:10 -04002045
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002046 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002047}
2048
2049bool Context::isResetNotificationEnabled()
2050{
2051 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2052}
2053
Corentin Walleze3b10e82015-05-20 11:06:25 -04002054const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002055{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002056 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002057}
2058
2059EGLenum Context::getClientType() const
2060{
2061 return mClientType;
2062}
2063
2064EGLenum Context::getRenderBuffer() const
2065{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002066 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2067 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002068 {
2069 return EGL_NONE;
2070 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002071
2072 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2073 ASSERT(backAttachment != nullptr);
2074 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002075}
2076
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002077VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002078{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002079 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002080 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2081 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002082 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002083 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2084 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002085
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002086 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002087 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002088
2089 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002090}
2091
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002092TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002093{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002094 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002095 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2096 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002097 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002098 transformFeedback =
2099 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002100 transformFeedback->addRef();
2101 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002102 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002103
2104 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002105}
2106
2107bool Context::isVertexArrayGenerated(GLuint vertexArray)
2108{
Geoff Langf41a7152016-09-19 15:11:17 -04002109 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002110 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2111}
2112
2113bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2114{
Geoff Langf41a7152016-09-19 15:11:17 -04002115 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002116 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2117}
2118
Shannon Woods53a94a82014-06-24 15:20:36 -04002119void Context::detachTexture(GLuint texture)
2120{
2121 // Simple pass-through to State's detachTexture method, as textures do not require
2122 // allocation map management either here or in the resource manager at detach time.
2123 // Zero textures are held by the Context, and we don't attempt to request them from
2124 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002125 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002126}
2127
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002128void Context::detachBuffer(GLuint buffer)
2129{
Yuly Novikov5807a532015-12-03 13:01:22 -05002130 // Simple pass-through to State's detachBuffer method, since
2131 // only buffer attachments to container objects that are bound to the current context
2132 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002133
Yuly Novikov5807a532015-12-03 13:01:22 -05002134 // [OpenGL ES 3.2] section 5.1.2 page 45:
2135 // Attachments to unbound container objects, such as
2136 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2137 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002138 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002139}
2140
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002141void Context::detachFramebuffer(GLuint framebuffer)
2142{
Shannon Woods53a94a82014-06-24 15:20:36 -04002143 // Framebuffer detachment is handled by Context, because 0 is a valid
2144 // Framebuffer object, and a pointer to it must be passed from Context
2145 // to State at binding time.
2146
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002147 // [OpenGL ES 2.0.24] section 4.4 page 107:
2148 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2149 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2150
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002151 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002152 {
2153 bindReadFramebuffer(0);
2154 }
2155
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002156 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002157 {
2158 bindDrawFramebuffer(0);
2159 }
2160}
2161
2162void Context::detachRenderbuffer(GLuint renderbuffer)
2163{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002164 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002165}
2166
Jamie Madill57a89722013-07-02 11:57:03 -04002167void Context::detachVertexArray(GLuint vertexArray)
2168{
Jamie Madill77a72f62015-04-14 11:18:32 -04002169 // Vertex array detachment is handled by Context, because 0 is a valid
2170 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002171 // binding time.
2172
Jamie Madill57a89722013-07-02 11:57:03 -04002173 // [OpenGL ES 3.0.2] section 2.10 page 43:
2174 // If a vertex array object that is currently bound is deleted, the binding
2175 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002176 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002177 {
2178 bindVertexArray(0);
2179 }
2180}
2181
Geoff Langc8058452014-02-03 12:04:11 -05002182void Context::detachTransformFeedback(GLuint transformFeedback)
2183{
Corentin Walleza2257da2016-04-19 16:43:12 -04002184 // Transform feedback detachment is handled by Context, because 0 is a valid
2185 // transform feedback, and a pointer to it must be passed from Context to State at
2186 // binding time.
2187
2188 // The OpenGL specification doesn't mention what should happen when the currently bound
2189 // transform feedback object is deleted. Since it is a container object, we treat it like
2190 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002191 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002192 {
2193 bindTransformFeedback(0);
2194 }
Geoff Langc8058452014-02-03 12:04:11 -05002195}
2196
Jamie Madilldc356042013-07-19 16:36:57 -04002197void Context::detachSampler(GLuint sampler)
2198{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002199 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002200}
2201
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002202void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2203{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002204 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002205}
2206
Jamie Madille29d1672013-07-19 16:36:57 -04002207void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2208{
Geoff Langc1984ed2016-10-07 12:41:00 -04002209 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002210 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002211 SetSamplerParameteri(samplerObject, pname, param);
2212}
Jamie Madille29d1672013-07-19 16:36:57 -04002213
Geoff Langc1984ed2016-10-07 12:41:00 -04002214void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2215{
2216 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002217 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002218 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002219}
2220
2221void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2222{
Geoff Langc1984ed2016-10-07 12:41:00 -04002223 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002224 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002225 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002226}
2227
Geoff Langc1984ed2016-10-07 12:41:00 -04002228void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002229{
Geoff Langc1984ed2016-10-07 12:41:00 -04002230 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002231 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002232 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002233}
2234
Geoff Langc1984ed2016-10-07 12:41:00 -04002235void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002236{
Geoff Langc1984ed2016-10-07 12:41:00 -04002237 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002238 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002239 QuerySamplerParameteriv(samplerObject, pname, params);
2240}
Jamie Madill9675b802013-07-19 16:36:59 -04002241
Geoff Langc1984ed2016-10-07 12:41:00 -04002242void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2243{
2244 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002245 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002246 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002247}
2248
Olli Etuahof0fee072016-03-30 15:11:58 +03002249void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2250{
2251 gl::Program *programObject = getProgram(program);
2252 ASSERT(programObject != nullptr);
2253
2254 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2255 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2256}
2257
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002258void Context::initRendererString()
2259{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002260 std::ostringstream rendererString;
2261 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002262 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002263 rendererString << ")";
2264
Geoff Langcec35902014-04-16 10:52:36 -04002265 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002266}
2267
Geoff Langc339c4e2016-11-29 10:37:36 -05002268void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002269{
Geoff Langc339c4e2016-11-29 10:37:36 -05002270 const Version &clientVersion = getClientVersion();
2271
2272 std::ostringstream versionString;
2273 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2274 << ANGLE_VERSION_STRING << ")";
2275 mVersionString = MakeStaticString(versionString.str());
2276
2277 std::ostringstream shadingLanguageVersionString;
2278 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2279 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2280 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2281 << ")";
2282 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002283}
2284
Geoff Langcec35902014-04-16 10:52:36 -04002285void Context::initExtensionStrings()
2286{
Geoff Langc339c4e2016-11-29 10:37:36 -05002287 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2288 std::ostringstream combinedStringStream;
2289 std::copy(strings.begin(), strings.end(),
2290 std::ostream_iterator<const char *>(combinedStringStream, " "));
2291 return MakeStaticString(combinedStringStream.str());
2292 };
2293
2294 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002295 for (const auto &extensionString : mExtensions.getStrings())
2296 {
2297 mExtensionStrings.push_back(MakeStaticString(extensionString));
2298 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002299 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002300
Bryan Bernhart58806562017-01-05 13:09:31 -08002301 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2302
Geoff Langc339c4e2016-11-29 10:37:36 -05002303 mRequestableExtensionStrings.clear();
2304 for (const auto &extensionInfo : GetExtensionInfoMap())
2305 {
2306 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002307 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2308 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002309 {
2310 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2311 }
2312 }
2313 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002314}
2315
Geoff Langc339c4e2016-11-29 10:37:36 -05002316const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002317{
Geoff Langc339c4e2016-11-29 10:37:36 -05002318 switch (name)
2319 {
2320 case GL_VENDOR:
2321 return reinterpret_cast<const GLubyte *>("Google Inc.");
2322
2323 case GL_RENDERER:
2324 return reinterpret_cast<const GLubyte *>(mRendererString);
2325
2326 case GL_VERSION:
2327 return reinterpret_cast<const GLubyte *>(mVersionString);
2328
2329 case GL_SHADING_LANGUAGE_VERSION:
2330 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2331
2332 case GL_EXTENSIONS:
2333 return reinterpret_cast<const GLubyte *>(mExtensionString);
2334
2335 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2336 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2337
2338 default:
2339 UNREACHABLE();
2340 return nullptr;
2341 }
Geoff Langcec35902014-04-16 10:52:36 -04002342}
2343
Geoff Langc339c4e2016-11-29 10:37:36 -05002344const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002345{
Geoff Langc339c4e2016-11-29 10:37:36 -05002346 switch (name)
2347 {
2348 case GL_EXTENSIONS:
2349 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2350
2351 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2352 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2353
2354 default:
2355 UNREACHABLE();
2356 return nullptr;
2357 }
Geoff Langcec35902014-04-16 10:52:36 -04002358}
2359
2360size_t Context::getExtensionStringCount() const
2361{
2362 return mExtensionStrings.size();
2363}
2364
Geoff Langc339c4e2016-11-29 10:37:36 -05002365void Context::requestExtension(const char *name)
2366{
2367 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2368 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2369 const auto &extension = extensionInfos.at(name);
2370 ASSERT(extension.Requestable);
2371
2372 if (mExtensions.*(extension.ExtensionsMember))
2373 {
2374 // Extension already enabled
2375 return;
2376 }
2377
2378 mExtensions.*(extension.ExtensionsMember) = true;
2379 updateCaps();
2380 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002381
2382 // Re-create the compiler with the requested extensions enabled.
2383 SafeDelete(mCompiler);
2384 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002385}
2386
2387size_t Context::getRequestableExtensionStringCount() const
2388{
2389 return mRequestableExtensionStrings.size();
2390}
2391
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002392void Context::beginTransformFeedback(GLenum primitiveMode)
2393{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002394 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002395 ASSERT(transformFeedback != nullptr);
2396 ASSERT(!transformFeedback->isPaused());
2397
Jamie Madill6c1f6712017-02-14 19:08:04 -05002398 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002399}
2400
2401bool Context::hasActiveTransformFeedback(GLuint program) const
2402{
2403 for (auto pair : mTransformFeedbackMap)
2404 {
2405 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2406 {
2407 return true;
2408 }
2409 }
2410 return false;
2411}
2412
Corentin Wallezc295e512017-01-27 17:47:50 -05002413void Context::initCaps(bool webGLContext, const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002414{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002415 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002416
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002417 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002418
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002419 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002420
Geoff Langeb66a6e2016-10-31 13:06:12 -04002421 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002422 {
2423 // Disable ES3+ extensions
2424 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002425 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002426 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002427 }
2428
Geoff Langeb66a6e2016-10-31 13:06:12 -04002429 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002430 {
2431 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2432 //mExtensions.sRGB = false;
2433 }
2434
Jamie Madill00ed7a12016-05-19 13:13:38 -04002435 // Some extensions are always available because they are implemented in the GL layer.
2436 mExtensions.bindUniformLocation = true;
2437 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002438 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002439 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002440 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002441
2442 // Enable the no error extension if the context was created with the flag.
2443 mExtensions.noError = mSkipValidation;
2444
Corentin Wallezccab69d2017-01-27 16:57:15 -05002445 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002446 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002447
Geoff Lang70d0f492015-12-10 17:45:46 -05002448 // Explicitly enable GL_KHR_debug
2449 mExtensions.debug = true;
2450 mExtensions.maxDebugMessageLength = 1024;
2451 mExtensions.maxDebugLoggedMessages = 1024;
2452 mExtensions.maxDebugGroupStackDepth = 1024;
2453 mExtensions.maxLabelLength = 1024;
2454
Geoff Langff5b2d52016-09-07 11:32:23 -04002455 // Explicitly enable GL_ANGLE_robust_client_memory
2456 mExtensions.robustClientMemory = true;
2457
Geoff Lang301d1612014-07-09 10:34:37 -04002458 // Apply implementation limits
2459 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002460 mCaps.maxVertexAttribBindings =
2461 getClientVersion() < ES_3_1
2462 ? mCaps.maxVertexAttributes
2463 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2464
Geoff Lang301d1612014-07-09 10:34:37 -04002465 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2466 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2467
2468 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002469
Geoff Langc287ea62016-09-16 14:46:51 -04002470 // WebGL compatibility
2471 mExtensions.webglCompatibility = webGLContext;
2472 for (const auto &extensionInfo : GetExtensionInfoMap())
2473 {
2474 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002475 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002476 {
2477 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2478 }
2479 }
2480
2481 // Generate texture caps
2482 updateCaps();
2483}
2484
2485void Context::updateCaps()
2486{
Geoff Lang900013c2014-07-07 11:32:19 -04002487 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002488 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002489
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002490 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002491 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2492 {
2493 GLenum format = i->first;
2494 TextureCaps formatCaps = i->second;
2495
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{
3789 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
3790 handleError(renderbuffer->setStorage(internalformat, width, height));
3791}
3792
3793void Context::renderbufferStorageMultisample(GLenum target,
3794 GLsizei samples,
3795 GLenum internalformat,
3796 GLsizei width,
3797 GLsizei height)
3798{
3799
3800 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
3801 handleError(renderbuffer->setStorageMultisample(samples, internalformat, width, height));
3802}
3803
Jamie Madillc29968b2016-01-20 11:17:23 -05003804} // namespace gl