blob: 89e0b04c4ca331625c775dc5616ce8b80efb34d0 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jiawei-Shao2597fb62016-12-09 16:38:02 +080029#include "libANGLE/queryutils.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
37#include "libANGLE/formatutils.h"
38#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070039#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040040#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040041#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030042#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040043#include "libANGLE/queryutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Ian Ewell3ffd78b2016-01-22 16:09:42 -050048template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050049std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030050 GLsizei numPaths,
51 const void *paths,
52 GLuint pathBase)
53{
54 std::vector<gl::Path *> ret;
55 ret.reserve(numPaths);
56
57 const auto *nameArray = static_cast<const T *>(paths);
58
59 for (GLsizei i = 0; i < numPaths; ++i)
60 {
61 const GLuint pathName = nameArray[i] + pathBase;
62
63 ret.push_back(resourceManager.getPath(pathName));
64 }
65
66 return ret;
67}
68
Geoff Lang4ddf5af2016-12-01 14:30:44 -050069std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030070 GLsizei numPaths,
71 GLenum pathNameType,
72 const void *paths,
73 GLuint pathBase)
74{
75 switch (pathNameType)
76 {
77 case GL_UNSIGNED_BYTE:
78 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_BYTE:
81 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_UNSIGNED_SHORT:
84 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_SHORT:
87 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_INT:
90 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_INT:
93 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
94 }
95
96 UNREACHABLE();
97 return std::vector<gl::Path *>();
98}
99
100template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400101gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500102{
Geoff Lang2186c382016-10-14 10:54:54 -0400103 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500104
105 switch (pname)
106 {
107 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400108 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109 case GL_QUERY_RESULT_AVAILABLE_EXT:
110 {
111 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400112 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500113 if (!error.isError())
114 {
Geoff Lang2186c382016-10-14 10:54:54 -0400115 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500116 }
117 return error;
118 }
119 default:
120 UNREACHABLE();
121 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
122 }
123}
124
Geoff Langf6db0982015-08-25 13:04:00 -0400125void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
126{
Geoff Lang1a683462015-09-29 15:09:59 -0400127 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400128 {
129 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
130 tfBufferIndex++)
131 {
132 const OffsetBindingPointer<gl::Buffer> &buffer =
133 transformFeedback->getIndexedBuffer(tfBufferIndex);
134 if (buffer.get() != nullptr)
135 {
136 buffer->onTransformFeedback();
137 }
138 }
139 }
140}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141
142// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300143EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400145 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146}
147
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
149{
150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
151}
152
Geoff Langeb66a6e2016-10-31 13:06:12 -0400153gl::Version GetClientVersion(const egl::AttributeMap &attribs)
154{
155 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
156}
157
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500158GLenum GetResetStrategy(const egl::AttributeMap &attribs)
159{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400160 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
161 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500162 switch (attrib)
163 {
164 case EGL_NO_RESET_NOTIFICATION:
165 return GL_NO_RESET_NOTIFICATION_EXT;
166 case EGL_LOSE_CONTEXT_ON_RESET:
167 return GL_LOSE_CONTEXT_ON_RESET_EXT;
168 default:
169 UNREACHABLE();
170 return GL_NONE;
171 }
172}
173
174bool GetRobustAccess(const egl::AttributeMap &attribs)
175{
Geoff Lang077f20a2016-11-01 10:08:02 -0400176 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
177 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
178 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500179}
180
181bool GetDebug(const egl::AttributeMap &attribs)
182{
Geoff Lang077f20a2016-11-01 10:08:02 -0400183 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
184 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetNoError(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
190}
191
Geoff Langc287ea62016-09-16 14:46:51 -0400192bool GetWebGLContext(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langf41a7152016-09-19 15:11:17 -0400197bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
200}
201
Geoff Langfeb8c682017-02-13 16:07:35 -0500202bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
205}
206
Martin Radev9d901792016-07-15 15:58:58 +0300207std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
208{
209 std::string labelName;
210 if (label != nullptr)
211 {
212 size_t labelLength = length < 0 ? strlen(label) : length;
213 labelName = std::string(label, labelLength);
214 }
215 return labelName;
216}
217
218void GetObjectLabelBase(const std::string &objectLabel,
219 GLsizei bufSize,
220 GLsizei *length,
221 GLchar *label)
222{
223 size_t writeLength = objectLabel.length();
224 if (label != nullptr && bufSize > 0)
225 {
226 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
227 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
228 label[writeLength] = '\0';
229 }
230
231 if (length != nullptr)
232 {
233 *length = static_cast<GLsizei>(writeLength);
234 }
235}
236
Geoff Langf6db0982015-08-25 13:04:00 -0400237} // anonymous namespace
238
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000239namespace gl
240{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000241
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400242Context::Context(rx::EGLImplFactory *implFactory,
243 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400244 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500245 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500246 const egl::AttributeMap &attribs,
247 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300248
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500249 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500250 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500251 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700252 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500253 mCaps,
254 mTextureCaps,
255 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500256 mLimitations,
257 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700258 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500259 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400260 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500261 mClientType(EGL_OPENGL_ES_API),
262 mHasBeenCurrent(false),
263 mContextLost(false),
264 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700265 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500266 mResetStrategy(GetResetStrategy(attribs)),
267 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500268 mCurrentSurface(nullptr),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500269 mSurfacelessFramebuffer(nullptr),
270 mWebGLContext(GetWebGLContext(attribs))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000271{
Geoff Lang077f20a2016-11-01 10:08:02 -0400272 if (mRobustAccess)
273 {
274 UNIMPLEMENTED();
275 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500277 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700278 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400279
Geoff Langeb66a6e2016-10-31 13:06:12 -0400280 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langfeb8c682017-02-13 16:07:35 -0500281 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100282
Shannon Woods53a94a82014-06-24 15:20:36 -0400283 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400284
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000285 // [OpenGL ES 2.0.24] section 3.7 page 83:
286 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
287 // and cube map texture state vectors respectively associated with them.
288 // In order that access to these initial textures not be lost, they are treated as texture
289 // objects all of whose names are 0.
290
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400291 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500292 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400296
Geoff Langeb66a6e2016-10-31 13:06:12 -0400297 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400298 {
299 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400300 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500301 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400302
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500304 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400305 }
Geoff Lang3b573612016-10-31 14:08:10 -0400306 if (getClientVersion() >= Version(3, 1))
307 {
308 Texture *zeroTexture2DMultisample =
309 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
310 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800311
312 bindGenericAtomicCounterBuffer(0);
313 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
314 {
315 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
316 }
Geoff Lang3b573612016-10-31 14:08:10 -0400317 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000318
Ian Ewellbda75592016-04-18 17:25:54 -0400319 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
320 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400321 Texture *zeroTextureExternal =
322 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400323 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
324 }
325
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700326 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500327
Jamie Madill57a89722013-07-02 11:57:03 -0400328 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000329 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800330 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000331 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400332
Jamie Madill01a80ee2016-11-07 12:06:18 -0500333 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000334
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000335 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500336 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000337 {
338 bindIndexedUniformBuffer(0, i, 0, -1);
339 }
340
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000341 bindCopyReadBuffer(0);
342 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000343 bindPixelPackBuffer(0);
344 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000345
Geoff Langeb66a6e2016-10-31 13:06:12 -0400346 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400347 {
348 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
349 // In the initial state, a default transform feedback object is bound and treated as
350 // a transform feedback object with a name of zero. That object is bound any time
351 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400352 bindTransformFeedback(0);
353 }
Geoff Langc8058452014-02-03 12:04:11 -0500354
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700355 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500356
357 // Initialize dirty bit masks
358 // TODO(jmadill): additional ES3 state
359 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
360 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
361 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
362 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
363 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
364 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400365 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500366 // No dirty objects.
367
368 // Readpixels uses the pack state and read FBO
369 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
370 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
371 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
372 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
373 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400374 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500375 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
376
377 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
378 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
379 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
380 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
381 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
382 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
383 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
384 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
385 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
386 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
387 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
388 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
389
390 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
391 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700392 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500393 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
394 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400395
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400396 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000397}
398
Jamie Madill70ee0f62017-02-06 16:04:20 -0500399void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000400{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500401 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000402
Corentin Wallez80b24112015-08-25 16:41:57 -0400403 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000404 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400405 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000406 }
407
Corentin Wallez80b24112015-08-25 16:41:57 -0400408 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000409 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400410 if (query.second != nullptr)
411 {
412 query.second->release();
413 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000414 }
415
Corentin Wallez80b24112015-08-25 16:41:57 -0400416 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400417 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400418 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400419 }
420
Corentin Wallez80b24112015-08-25 16:41:57 -0400421 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500422 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500423 if (transformFeedback.second != nullptr)
424 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500425 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500426 }
Geoff Langc8058452014-02-03 12:04:11 -0500427 }
428
Jamie Madilldedd7b92014-11-05 16:30:36 -0500429 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400430 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500431 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400432 }
433 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000434
Corentin Wallezccab69d2017-01-27 16:57:15 -0500435 SafeDelete(mSurfacelessFramebuffer);
436
Jamie Madill70ee0f62017-02-06 16:04:20 -0500437 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400438
Geoff Lang492a7e42014-11-05 13:27:06 -0500439 SafeDelete(mCompiler);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500440
441 mState.mBuffers->release(this);
442 mState.mShaderPrograms->release(this);
443 mState.mTextures->release(this);
444 mState.mRenderbuffers->release(this);
445 mState.mSamplers->release(this);
446 mState.mFenceSyncs->release(this);
447 mState.mPaths->release(this);
448 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000449}
450
Jamie Madill70ee0f62017-02-06 16:04:20 -0500451Context::~Context()
452{
453}
454
455void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000456{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000457 if (!mHasBeenCurrent)
458 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000459 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500460 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400461 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000462
Corentin Wallezc295e512017-01-27 17:47:50 -0500463 int width = 0;
464 int height = 0;
465 if (surface != nullptr)
466 {
467 width = surface->getWidth();
468 height = surface->getHeight();
469 }
470
471 mGLState.setViewportParams(0, 0, width, height);
472 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000473
474 mHasBeenCurrent = true;
475 }
476
Jamie Madill1b94d432015-08-07 13:23:23 -0400477 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700478 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400479
Jamie Madill70ee0f62017-02-06 16:04:20 -0500480 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500481
482 Framebuffer *newDefault = nullptr;
483 if (surface != nullptr)
484 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500485 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500486 mCurrentSurface = surface;
487 newDefault = surface->getDefaultFramebuffer();
488 }
489 else
490 {
491 if (mSurfacelessFramebuffer == nullptr)
492 {
493 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
494 }
495
496 newDefault = mSurfacelessFramebuffer;
497 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000498
Corentin Wallez37c39792015-08-20 14:19:46 -0400499 // Update default framebuffer, the binding of the previous default
500 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400501 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700502 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400503 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700504 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400505 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700506 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400507 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700508 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400509 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500510 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400511 }
Ian Ewell292f0052016-02-04 10:37:32 -0500512
513 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700514 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000515}
516
Jamie Madill70ee0f62017-02-06 16:04:20 -0500517void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400518{
Corentin Wallez37c39792015-08-20 14:19:46 -0400519 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500520 Framebuffer *currentDefault = nullptr;
521 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400522 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500523 currentDefault = mCurrentSurface->getDefaultFramebuffer();
524 }
525 else if (mSurfacelessFramebuffer != nullptr)
526 {
527 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400528 }
529
Corentin Wallezc295e512017-01-27 17:47:50 -0500530 if (mGLState.getReadFramebuffer() == currentDefault)
531 {
532 mGLState.setReadFramebufferBinding(nullptr);
533 }
534 if (mGLState.getDrawFramebuffer() == currentDefault)
535 {
536 mGLState.setDrawFramebufferBinding(nullptr);
537 }
538 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
539
540 if (mCurrentSurface)
541 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500542 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500543 mCurrentSurface = nullptr;
544 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400545}
546
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000547GLuint Context::createBuffer()
548{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500549 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000550}
551
552GLuint Context::createProgram()
553{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500554 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000555}
556
557GLuint Context::createShader(GLenum type)
558{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500559 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000560}
561
562GLuint Context::createTexture()
563{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500564 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000565}
566
567GLuint Context::createRenderbuffer()
568{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500569 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000570}
571
Geoff Lang882033e2014-09-30 11:26:07 -0400572GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400573{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500574 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400575
Cooper Partind8e62a32015-01-29 15:21:25 -0800576 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400577}
578
Sami Väisänene45e53b2016-05-25 10:36:04 +0300579GLuint Context::createPaths(GLsizei range)
580{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500581 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300582 if (resultOrError.isError())
583 {
584 handleError(resultOrError.getError());
585 return 0;
586 }
587 return resultOrError.getResult();
588}
589
Jamie Madill57a89722013-07-02 11:57:03 -0400590GLuint Context::createVertexArray()
591{
Geoff Lang36167ab2015-12-07 10:27:14 -0500592 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
593 mVertexArrayMap[vertexArray] = nullptr;
594 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400595}
596
Jamie Madilldc356042013-07-19 16:36:57 -0400597GLuint Context::createSampler()
598{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500599 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400600}
601
Geoff Langc8058452014-02-03 12:04:11 -0500602GLuint Context::createTransformFeedback()
603{
Geoff Lang36167ab2015-12-07 10:27:14 -0500604 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
605 mTransformFeedbackMap[transformFeedback] = nullptr;
606 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500607}
608
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000609// Returns an unused framebuffer name
610GLuint Context::createFramebuffer()
611{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500612 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000613}
614
Jamie Madill33dc8432013-07-26 11:55:05 -0400615GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000616{
Jamie Madill33dc8432013-07-26 11:55:05 -0400617 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000618
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400619 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620
621 return handle;
622}
623
624// Returns an unused query name
625GLuint Context::createQuery()
626{
627 GLuint handle = mQueryHandleAllocator.allocate();
628
629 mQueryMap[handle] = NULL;
630
631 return handle;
632}
633
634void Context::deleteBuffer(GLuint buffer)
635{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500636 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637 {
638 detachBuffer(buffer);
639 }
Jamie Madill893ab082014-05-16 16:56:10 -0400640
Jamie Madill6c1f6712017-02-14 19:08:04 -0500641 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000642}
643
644void Context::deleteShader(GLuint shader)
645{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500646 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000647}
648
649void Context::deleteProgram(GLuint program)
650{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500651 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000652}
653
654void Context::deleteTexture(GLuint texture)
655{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500656 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000657 {
658 detachTexture(texture);
659 }
660
Jamie Madill6c1f6712017-02-14 19:08:04 -0500661 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000662}
663
664void Context::deleteRenderbuffer(GLuint renderbuffer)
665{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500666 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000667 {
668 detachRenderbuffer(renderbuffer);
669 }
Jamie Madill893ab082014-05-16 16:56:10 -0400670
Jamie Madill6c1f6712017-02-14 19:08:04 -0500671 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000672}
673
Jamie Madillcd055f82013-07-26 11:55:15 -0400674void Context::deleteFenceSync(GLsync fenceSync)
675{
676 // The spec specifies the underlying Fence object is not deleted until all current
677 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
678 // and since our API is currently designed for being called from a single thread, we can delete
679 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500680 mState.mFenceSyncs->deleteObject(this,
681 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400682}
683
Sami Väisänene45e53b2016-05-25 10:36:04 +0300684void Context::deletePaths(GLuint first, GLsizei range)
685{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500686 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300687}
688
689bool Context::hasPathData(GLuint path) const
690{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500691 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300692 if (pathObj == nullptr)
693 return false;
694
695 return pathObj->hasPathData();
696}
697
698bool Context::hasPath(GLuint path) const
699{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500700 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300701}
702
703void Context::setPathCommands(GLuint path,
704 GLsizei numCommands,
705 const GLubyte *commands,
706 GLsizei numCoords,
707 GLenum coordType,
708 const void *coords)
709{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500710 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300711
712 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
713}
714
715void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
716{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500717 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300718
719 switch (pname)
720 {
721 case GL_PATH_STROKE_WIDTH_CHROMIUM:
722 pathObj->setStrokeWidth(value);
723 break;
724 case GL_PATH_END_CAPS_CHROMIUM:
725 pathObj->setEndCaps(static_cast<GLenum>(value));
726 break;
727 case GL_PATH_JOIN_STYLE_CHROMIUM:
728 pathObj->setJoinStyle(static_cast<GLenum>(value));
729 break;
730 case GL_PATH_MITER_LIMIT_CHROMIUM:
731 pathObj->setMiterLimit(value);
732 break;
733 case GL_PATH_STROKE_BOUND_CHROMIUM:
734 pathObj->setStrokeBound(value);
735 break;
736 default:
737 UNREACHABLE();
738 break;
739 }
740}
741
742void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
743{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500744 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300745
746 switch (pname)
747 {
748 case GL_PATH_STROKE_WIDTH_CHROMIUM:
749 *value = pathObj->getStrokeWidth();
750 break;
751 case GL_PATH_END_CAPS_CHROMIUM:
752 *value = static_cast<GLfloat>(pathObj->getEndCaps());
753 break;
754 case GL_PATH_JOIN_STYLE_CHROMIUM:
755 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
756 break;
757 case GL_PATH_MITER_LIMIT_CHROMIUM:
758 *value = pathObj->getMiterLimit();
759 break;
760 case GL_PATH_STROKE_BOUND_CHROMIUM:
761 *value = pathObj->getStrokeBound();
762 break;
763 default:
764 UNREACHABLE();
765 break;
766 }
767}
768
769void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
770{
771 mGLState.setPathStencilFunc(func, ref, mask);
772}
773
Jamie Madill57a89722013-07-02 11:57:03 -0400774void Context::deleteVertexArray(GLuint vertexArray)
775{
Geoff Lang36167ab2015-12-07 10:27:14 -0500776 auto iter = mVertexArrayMap.find(vertexArray);
777 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000778 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500779 VertexArray *vertexArrayObject = iter->second;
780 if (vertexArrayObject != nullptr)
781 {
782 detachVertexArray(vertexArray);
783 delete vertexArrayObject;
784 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000785
Geoff Lang36167ab2015-12-07 10:27:14 -0500786 mVertexArrayMap.erase(iter);
787 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400788 }
789}
790
Jamie Madilldc356042013-07-19 16:36:57 -0400791void Context::deleteSampler(GLuint sampler)
792{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500793 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400794 {
795 detachSampler(sampler);
796 }
797
Jamie Madill6c1f6712017-02-14 19:08:04 -0500798 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400799}
800
Geoff Langc8058452014-02-03 12:04:11 -0500801void Context::deleteTransformFeedback(GLuint transformFeedback)
802{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500803 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500804 if (iter != mTransformFeedbackMap.end())
805 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500806 TransformFeedback *transformFeedbackObject = iter->second;
807 if (transformFeedbackObject != nullptr)
808 {
809 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500810 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500811 }
812
Geoff Lang50b3fe82015-12-08 14:49:12 +0000813 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500814 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500815 }
816}
817
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000818void Context::deleteFramebuffer(GLuint framebuffer)
819{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500820 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821 {
822 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000823 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500824
Jamie Madill6c1f6712017-02-14 19:08:04 -0500825 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000826}
827
Jamie Madill33dc8432013-07-26 11:55:05 -0400828void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000829{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500830 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000831
Jamie Madill33dc8432013-07-26 11:55:05 -0400832 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000833 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400834 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400836 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837 }
838}
839
840void Context::deleteQuery(GLuint query)
841{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500842 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843 if (queryObject != mQueryMap.end())
844 {
845 mQueryHandleAllocator.release(queryObject->first);
846 if (queryObject->second)
847 {
848 queryObject->second->release();
849 }
850 mQueryMap.erase(queryObject);
851 }
852}
853
Geoff Lang70d0f492015-12-10 17:45:46 -0500854Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500856 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000857}
858
Jamie Madill570f7c82014-07-03 10:38:54 -0400859Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000860{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500861 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000862}
863
Geoff Lang70d0f492015-12-10 17:45:46 -0500864Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000865{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500866 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000867}
868
Jamie Madillcd055f82013-07-26 11:55:15 -0400869FenceSync *Context::getFenceSync(GLsync handle) const
870{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500871 return mState.mFenceSyncs->getFenceSync(
872 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400873}
874
Jamie Madill57a89722013-07-02 11:57:03 -0400875VertexArray *Context::getVertexArray(GLuint handle) const
876{
877 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500878 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400879}
880
Jamie Madilldc356042013-07-19 16:36:57 -0400881Sampler *Context::getSampler(GLuint handle) const
882{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500883 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400884}
885
Geoff Langc8058452014-02-03 12:04:11 -0500886TransformFeedback *Context::getTransformFeedback(GLuint handle) const
887{
Geoff Lang36167ab2015-12-07 10:27:14 -0500888 auto iter = mTransformFeedbackMap.find(handle);
889 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500890}
891
Geoff Lang70d0f492015-12-10 17:45:46 -0500892LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
893{
894 switch (identifier)
895 {
896 case GL_BUFFER:
897 return getBuffer(name);
898 case GL_SHADER:
899 return getShader(name);
900 case GL_PROGRAM:
901 return getProgram(name);
902 case GL_VERTEX_ARRAY:
903 return getVertexArray(name);
904 case GL_QUERY:
905 return getQuery(name);
906 case GL_TRANSFORM_FEEDBACK:
907 return getTransformFeedback(name);
908 case GL_SAMPLER:
909 return getSampler(name);
910 case GL_TEXTURE:
911 return getTexture(name);
912 case GL_RENDERBUFFER:
913 return getRenderbuffer(name);
914 case GL_FRAMEBUFFER:
915 return getFramebuffer(name);
916 default:
917 UNREACHABLE();
918 return nullptr;
919 }
920}
921
922LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
923{
924 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
925}
926
Martin Radev9d901792016-07-15 15:58:58 +0300927void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
928{
929 LabeledObject *object = getLabeledObject(identifier, name);
930 ASSERT(object != nullptr);
931
932 std::string labelName = GetObjectLabelFromPointer(length, label);
933 object->setLabel(labelName);
934}
935
936void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
937{
938 LabeledObject *object = getLabeledObjectFromPtr(ptr);
939 ASSERT(object != nullptr);
940
941 std::string labelName = GetObjectLabelFromPointer(length, label);
942 object->setLabel(labelName);
943}
944
945void Context::getObjectLabel(GLenum identifier,
946 GLuint name,
947 GLsizei bufSize,
948 GLsizei *length,
949 GLchar *label) const
950{
951 LabeledObject *object = getLabeledObject(identifier, name);
952 ASSERT(object != nullptr);
953
954 const std::string &objectLabel = object->getLabel();
955 GetObjectLabelBase(objectLabel, bufSize, length, label);
956}
957
958void Context::getObjectPtrLabel(const void *ptr,
959 GLsizei bufSize,
960 GLsizei *length,
961 GLchar *label) const
962{
963 LabeledObject *object = getLabeledObjectFromPtr(ptr);
964 ASSERT(object != nullptr);
965
966 const std::string &objectLabel = object->getLabel();
967 GetObjectLabelBase(objectLabel, bufSize, length, label);
968}
969
Jamie Madilldc356042013-07-19 16:36:57 -0400970bool Context::isSampler(GLuint samplerName) const
971{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500972 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400973}
974
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500975void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500977 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700978 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000979}
980
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800981void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
982{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500983 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800984 mGLState.setDrawIndirectBufferBinding(buffer);
985}
986
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500987void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000988{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500989 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700990 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000991}
992
Jamie Madilldedd7b92014-11-05 16:30:36 -0500993void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000994{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500995 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996
Jamie Madilldedd7b92014-11-05 16:30:36 -0500997 if (handle == 0)
998 {
999 texture = mZeroTextures[target].get();
1000 }
1001 else
1002 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001003 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001004 }
1005
1006 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001007 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001008}
1009
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001010void Context::bindReadFramebuffer(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.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001015}
1016
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001017void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001018{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001019 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1020 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001022}
1023
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001025{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001026 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001028}
1029
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001030void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001031{
Geoff Lang76b10c92014-09-05 16:28:14 -04001032 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001033 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001034 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001035 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001036}
1037
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001038void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001039{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001040 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001041 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001042}
1043
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001044void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1045 GLuint index,
1046 GLintptr offset,
1047 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001048{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001049 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001050 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001051}
1052
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001053void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001054{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001055 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001056 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001057}
1058
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001059void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1060 GLuint index,
1061 GLintptr offset,
1062 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001063{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001064 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001065 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001066}
1067
Jiajia Qin6eafb042016-12-27 17:04:07 +08001068void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1069{
1070 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1071 mGLState.setGenericAtomicCounterBufferBinding(buffer);
1072}
1073
1074void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1075 GLuint index,
1076 GLintptr offset,
1077 GLsizeiptr size)
1078{
1079 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1080 mGLState.setIndexedAtomicCounterBufferBinding(index, buffer, offset, size);
1081}
1082
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001083void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001084{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001085 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001086 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001087}
1088
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001089void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001090{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001091 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001092 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001093}
1094
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001095void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001096{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001097 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001098 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001099}
1100
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001101void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001102{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001103 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001104 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001105}
1106
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001107void Context::useProgram(GLuint program)
1108{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001109 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001110}
1111
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001112void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001113{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001114 TransformFeedback *transformFeedback =
1115 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001116 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001117}
1118
Geoff Lang5aad9672014-09-08 11:10:42 -04001119Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001120{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001121 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001122 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001123
Geoff Lang5aad9672014-09-08 11:10:42 -04001124 // begin query
1125 Error error = queryObject->begin();
1126 if (error.isError())
1127 {
1128 return error;
1129 }
1130
1131 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001132 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001133
He Yunchaoacd18982017-01-04 10:46:42 +08001134 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001135}
1136
Geoff Lang5aad9672014-09-08 11:10:42 -04001137Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001138{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001139 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001140 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001141
Geoff Lang5aad9672014-09-08 11:10:42 -04001142 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001143
Geoff Lang5aad9672014-09-08 11:10:42 -04001144 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001145 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001146
1147 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001148}
1149
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001150Error Context::queryCounter(GLuint id, GLenum target)
1151{
1152 ASSERT(target == GL_TIMESTAMP_EXT);
1153
1154 Query *queryObject = getQuery(id, true, target);
1155 ASSERT(queryObject);
1156
1157 return queryObject->queryCounter();
1158}
1159
1160void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1161{
1162 switch (pname)
1163 {
1164 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001165 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001166 break;
1167 case GL_QUERY_COUNTER_BITS_EXT:
1168 switch (target)
1169 {
1170 case GL_TIME_ELAPSED_EXT:
1171 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1172 break;
1173 case GL_TIMESTAMP_EXT:
1174 params[0] = getExtensions().queryCounterBitsTimestamp;
1175 break;
1176 default:
1177 UNREACHABLE();
1178 params[0] = 0;
1179 break;
1180 }
1181 break;
1182 default:
1183 UNREACHABLE();
1184 return;
1185 }
1186}
1187
Geoff Lang2186c382016-10-14 10:54:54 -04001188void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001189{
Geoff Lang2186c382016-10-14 10:54:54 -04001190 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001191}
1192
Geoff Lang2186c382016-10-14 10:54:54 -04001193void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001194{
Geoff Lang2186c382016-10-14 10:54:54 -04001195 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001196}
1197
Geoff Lang2186c382016-10-14 10:54:54 -04001198void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001199{
Geoff Lang2186c382016-10-14 10:54:54 -04001200 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001201}
1202
Geoff Lang2186c382016-10-14 10:54:54 -04001203void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001204{
Geoff Lang2186c382016-10-14 10:54:54 -04001205 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001206}
1207
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001208Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001209{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001210 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001211}
1212
Jamie Madill33dc8432013-07-26 11:55:05 -04001213FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001214{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001215 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216
Jamie Madill33dc8432013-07-26 11:55:05 -04001217 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218 {
1219 return NULL;
1220 }
1221 else
1222 {
1223 return fence->second;
1224 }
1225}
1226
1227Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1228{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001229 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001230
1231 if (query == mQueryMap.end())
1232 {
1233 return NULL;
1234 }
1235 else
1236 {
1237 if (!query->second && create)
1238 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001239 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240 query->second->addRef();
1241 }
1242 return query->second;
1243 }
1244}
1245
Geoff Lang70d0f492015-12-10 17:45:46 -05001246Query *Context::getQuery(GLuint handle) const
1247{
1248 auto iter = mQueryMap.find(handle);
1249 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1250}
1251
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001252Texture *Context::getTargetTexture(GLenum target) const
1253{
Ian Ewellbda75592016-04-18 17:25:54 -04001254 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001255 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001256}
1257
Geoff Lang76b10c92014-09-05 16:28:14 -04001258Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001259{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001260 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001261}
1262
Geoff Lang492a7e42014-11-05 13:27:06 -05001263Compiler *Context::getCompiler() const
1264{
1265 return mCompiler;
1266}
1267
Jamie Madill893ab082014-05-16 16:56:10 -04001268void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001269{
1270 switch (pname)
1271 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001272 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001273 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001275 mGLState.getBooleanv(pname, params);
1276 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278}
1279
Jamie Madill893ab082014-05-16 16:56:10 -04001280void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281{
Shannon Woods53a94a82014-06-24 15:20:36 -04001282 // Queries about context capabilities and maximums are answered by Context.
1283 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284 switch (pname)
1285 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001286 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001287 params[0] = mCaps.minAliasedLineWidth;
1288 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001289 break;
1290 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001291 params[0] = mCaps.minAliasedPointSize;
1292 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001293 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001294 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001295 ASSERT(mExtensions.textureFilterAnisotropic);
1296 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001297 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001298 case GL_MAX_TEXTURE_LOD_BIAS:
1299 *params = mCaps.maxLODBias;
1300 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001301
1302 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1303 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1304 {
1305 ASSERT(mExtensions.pathRendering);
1306 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1307 memcpy(params, m, 16 * sizeof(GLfloat));
1308 }
1309 break;
1310
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001311 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001312 mGLState.getFloatv(pname, params);
1313 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001314 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001315}
1316
Jamie Madill893ab082014-05-16 16:56:10 -04001317void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001318{
Shannon Woods53a94a82014-06-24 15:20:36 -04001319 // Queries about context capabilities and maximums are answered by Context.
1320 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001321
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322 switch (pname)
1323 {
Geoff Lang301d1612014-07-09 10:34:37 -04001324 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1325 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1326 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001327 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1328 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1329 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001330 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1331 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1332 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001333 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001334 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1335 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1336 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001337 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001338 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001339 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1340 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1341 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1342 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001343 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1344 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001345 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1346 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001347 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001348 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1349 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1350 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1351 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001352 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001353 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001354 break;
1355 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001356 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001357 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001358 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1359 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001360 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1361 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1362 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001363 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1364 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1365 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001366 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001367 case GL_MAX_VIEWPORT_DIMS:
1368 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001369 params[0] = mCaps.maxViewportWidth;
1370 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001371 }
1372 break;
1373 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001374 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001375 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001376 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1377 *params = mResetStrategy;
1378 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001379 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001380 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001381 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001382 case GL_SHADER_BINARY_FORMATS:
1383 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1384 break;
1385 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001386 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001387 break;
1388 case GL_PROGRAM_BINARY_FORMATS:
1389 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001390 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001391 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001392 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001393 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001394
1395 // GL_KHR_debug
1396 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1397 *params = mExtensions.maxDebugMessageLength;
1398 break;
1399 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1400 *params = mExtensions.maxDebugLoggedMessages;
1401 break;
1402 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1403 *params = mExtensions.maxDebugGroupStackDepth;
1404 break;
1405 case GL_MAX_LABEL_LENGTH:
1406 *params = mExtensions.maxLabelLength;
1407 break;
1408
Ian Ewell53f59f42016-01-28 17:36:55 -05001409 // GL_EXT_disjoint_timer_query
1410 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001411 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001412 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001413 case GL_MAX_FRAMEBUFFER_WIDTH:
1414 *params = mCaps.maxFramebufferWidth;
1415 break;
1416 case GL_MAX_FRAMEBUFFER_HEIGHT:
1417 *params = mCaps.maxFramebufferHeight;
1418 break;
1419 case GL_MAX_FRAMEBUFFER_SAMPLES:
1420 *params = mCaps.maxFramebufferSamples;
1421 break;
1422 case GL_MAX_SAMPLE_MASK_WORDS:
1423 *params = mCaps.maxSampleMaskWords;
1424 break;
1425 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1426 *params = mCaps.maxColorTextureSamples;
1427 break;
1428 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1429 *params = mCaps.maxDepthTextureSamples;
1430 break;
1431 case GL_MAX_INTEGER_SAMPLES:
1432 *params = mCaps.maxIntegerSamples;
1433 break;
1434 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1435 *params = mCaps.maxVertexAttribRelativeOffset;
1436 break;
1437 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1438 *params = mCaps.maxVertexAttribBindings;
1439 break;
1440 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1441 *params = mCaps.maxVertexAttribStride;
1442 break;
1443 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1444 *params = mCaps.maxVertexAtomicCounterBuffers;
1445 break;
1446 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1447 *params = mCaps.maxVertexAtomicCounters;
1448 break;
1449 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1450 *params = mCaps.maxVertexImageUniforms;
1451 break;
1452 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1453 *params = mCaps.maxVertexShaderStorageBlocks;
1454 break;
1455 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1456 *params = mCaps.maxFragmentAtomicCounterBuffers;
1457 break;
1458 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1459 *params = mCaps.maxFragmentAtomicCounters;
1460 break;
1461 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1462 *params = mCaps.maxFragmentImageUniforms;
1463 break;
1464 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1465 *params = mCaps.maxFragmentShaderStorageBlocks;
1466 break;
1467 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1468 *params = mCaps.minProgramTextureGatherOffset;
1469 break;
1470 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1471 *params = mCaps.maxProgramTextureGatherOffset;
1472 break;
1473 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1474 *params = mCaps.maxComputeWorkGroupInvocations;
1475 break;
1476 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1477 *params = mCaps.maxComputeUniformBlocks;
1478 break;
1479 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1480 *params = mCaps.maxComputeTextureImageUnits;
1481 break;
1482 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1483 *params = mCaps.maxComputeSharedMemorySize;
1484 break;
1485 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1486 *params = mCaps.maxComputeUniformComponents;
1487 break;
1488 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1489 *params = mCaps.maxComputeAtomicCounterBuffers;
1490 break;
1491 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1492 *params = mCaps.maxComputeAtomicCounters;
1493 break;
1494 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1495 *params = mCaps.maxComputeImageUniforms;
1496 break;
1497 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1498 *params = mCaps.maxCombinedComputeUniformComponents;
1499 break;
1500 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1501 *params = mCaps.maxComputeShaderStorageBlocks;
1502 break;
1503 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1504 *params = mCaps.maxCombinedShaderOutputResources;
1505 break;
1506 case GL_MAX_UNIFORM_LOCATIONS:
1507 *params = mCaps.maxUniformLocations;
1508 break;
1509 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1510 *params = mCaps.maxAtomicCounterBufferBindings;
1511 break;
1512 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1513 *params = mCaps.maxAtomicCounterBufferSize;
1514 break;
1515 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1516 *params = mCaps.maxCombinedAtomicCounterBuffers;
1517 break;
1518 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1519 *params = mCaps.maxCombinedAtomicCounters;
1520 break;
1521 case GL_MAX_IMAGE_UNITS:
1522 *params = mCaps.maxImageUnits;
1523 break;
1524 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1525 *params = mCaps.maxCombinedImageUniforms;
1526 break;
1527 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1528 *params = mCaps.maxShaderStorageBufferBindings;
1529 break;
1530 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1531 *params = mCaps.maxCombinedShaderStorageBlocks;
1532 break;
1533 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1534 *params = mCaps.shaderStorageBufferOffsetAlignment;
1535 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001536 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001537 mGLState.getIntegerv(mState, pname, params);
1538 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001539 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001540}
1541
Jamie Madill893ab082014-05-16 16:56:10 -04001542void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001543{
Shannon Woods53a94a82014-06-24 15:20:36 -04001544 // Queries about context capabilities and maximums are answered by Context.
1545 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001546 switch (pname)
1547 {
1548 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001549 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001550 break;
1551 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001552 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001553 break;
1554 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001555 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001556 break;
1557 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001558 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001559 break;
1560 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001561 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001562 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001563
1564 // GL_EXT_disjoint_timer_query
1565 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001566 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001567 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001568
1569 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1570 *params = mCaps.maxShaderStorageBlockSize;
1571 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001572 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001573 UNREACHABLE();
1574 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001575 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001576}
1577
Geoff Lang70d0f492015-12-10 17:45:46 -05001578void Context::getPointerv(GLenum pname, void **params) const
1579{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001580 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001581}
1582
Martin Radev66fb8202016-07-28 11:45:20 +03001583void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001584{
Shannon Woods53a94a82014-06-24 15:20:36 -04001585 // Queries about context capabilities and maximums are answered by Context.
1586 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001587
1588 GLenum nativeType;
1589 unsigned int numParams;
1590 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1591 ASSERT(queryStatus);
1592
1593 if (nativeType == GL_INT)
1594 {
1595 switch (target)
1596 {
1597 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1598 ASSERT(index < 3u);
1599 *data = mCaps.maxComputeWorkGroupCount[index];
1600 break;
1601 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1602 ASSERT(index < 3u);
1603 *data = mCaps.maxComputeWorkGroupSize[index];
1604 break;
1605 default:
1606 mGLState.getIntegeri_v(target, index, data);
1607 }
1608 }
1609 else
1610 {
1611 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1612 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001613}
1614
Martin Radev66fb8202016-07-28 11:45:20 +03001615void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001616{
Shannon Woods53a94a82014-06-24 15:20:36 -04001617 // Queries about context capabilities and maximums are answered by Context.
1618 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001619
1620 GLenum nativeType;
1621 unsigned int numParams;
1622 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1623 ASSERT(queryStatus);
1624
1625 if (nativeType == GL_INT_64_ANGLEX)
1626 {
1627 mGLState.getInteger64i_v(target, index, data);
1628 }
1629 else
1630 {
1631 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1632 }
1633}
1634
1635void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1636{
1637 // Queries about context capabilities and maximums are answered by Context.
1638 // Queries about current GL state values are answered by State.
1639
1640 GLenum nativeType;
1641 unsigned int numParams;
1642 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1643 ASSERT(queryStatus);
1644
1645 if (nativeType == GL_BOOL)
1646 {
1647 mGLState.getBooleani_v(target, index, data);
1648 }
1649 else
1650 {
1651 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1652 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001653}
1654
Jamie Madill675fe712016-12-19 13:07:54 -05001655void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001656{
Jamie Madill1b94d432015-08-07 13:23:23 -04001657 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001658 auto error = mImplementation->drawArrays(mode, first, count);
1659 handleError(error);
1660 if (!error.isError())
1661 {
1662 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1663 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001664}
1665
Jamie Madill675fe712016-12-19 13:07:54 -05001666void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001667{
1668 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001669 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1670 handleError(error);
1671 if (!error.isError())
1672 {
1673 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1674 }
Geoff Langf6db0982015-08-25 13:04:00 -04001675}
1676
Jamie Madill675fe712016-12-19 13:07:54 -05001677void Context::drawElements(GLenum mode,
1678 GLsizei count,
1679 GLenum type,
1680 const GLvoid *indices,
1681 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001682{
Jamie Madill1b94d432015-08-07 13:23:23 -04001683 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001684 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001685}
1686
Jamie Madill675fe712016-12-19 13:07:54 -05001687void Context::drawElementsInstanced(GLenum mode,
1688 GLsizei count,
1689 GLenum type,
1690 const GLvoid *indices,
1691 GLsizei instances,
1692 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001693{
1694 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001695 handleError(
1696 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001697}
1698
Jamie Madill675fe712016-12-19 13:07:54 -05001699void Context::drawRangeElements(GLenum mode,
1700 GLuint start,
1701 GLuint end,
1702 GLsizei count,
1703 GLenum type,
1704 const GLvoid *indices,
1705 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001706{
1707 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001708 handleError(
1709 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001710}
1711
Jiajia Qind9671222016-11-29 16:30:31 +08001712void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1713{
1714 syncRendererState();
1715 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1716}
1717
1718void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1719{
1720 syncRendererState();
1721 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1722}
1723
Jamie Madill675fe712016-12-19 13:07:54 -05001724void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001725{
Jamie Madill675fe712016-12-19 13:07:54 -05001726 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001727}
1728
Jamie Madill675fe712016-12-19 13:07:54 -05001729void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001730{
Jamie Madill675fe712016-12-19 13:07:54 -05001731 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001732}
1733
Austin Kinross6ee1e782015-05-29 17:05:37 -07001734void Context::insertEventMarker(GLsizei length, const char *marker)
1735{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001736 ASSERT(mImplementation);
1737 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001738}
1739
1740void Context::pushGroupMarker(GLsizei length, const char *marker)
1741{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001742 ASSERT(mImplementation);
1743 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001744}
1745
1746void Context::popGroupMarker()
1747{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001748 ASSERT(mImplementation);
1749 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001750}
1751
Geoff Langd8605522016-04-13 10:19:12 -04001752void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1753{
1754 Program *programObject = getProgram(program);
1755 ASSERT(programObject);
1756
1757 programObject->bindUniformLocation(location, name);
1758}
1759
Sami Väisänena797e062016-05-12 15:23:40 +03001760void Context::setCoverageModulation(GLenum components)
1761{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001762 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001763}
1764
Sami Väisänene45e53b2016-05-25 10:36:04 +03001765void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1766{
1767 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1768}
1769
1770void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1771{
1772 GLfloat I[16];
1773 angle::Matrix<GLfloat>::setToIdentity(I);
1774
1775 mGLState.loadPathRenderingMatrix(matrixMode, I);
1776}
1777
1778void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1779{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001780 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001781 if (!pathObj)
1782 return;
1783
1784 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1785 syncRendererState();
1786
1787 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1788}
1789
1790void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1791{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001792 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001793 if (!pathObj)
1794 return;
1795
1796 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1797 syncRendererState();
1798
1799 mImplementation->stencilStrokePath(pathObj, reference, mask);
1800}
1801
1802void Context::coverFillPath(GLuint path, GLenum coverMode)
1803{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001804 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001805 if (!pathObj)
1806 return;
1807
1808 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1809 syncRendererState();
1810
1811 mImplementation->coverFillPath(pathObj, coverMode);
1812}
1813
1814void Context::coverStrokePath(GLuint path, GLenum coverMode)
1815{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001816 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001817 if (!pathObj)
1818 return;
1819
1820 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1821 syncRendererState();
1822
1823 mImplementation->coverStrokePath(pathObj, coverMode);
1824}
1825
1826void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1827{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001828 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001829 if (!pathObj)
1830 return;
1831
1832 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1833 syncRendererState();
1834
1835 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1836}
1837
1838void Context::stencilThenCoverStrokePath(GLuint path,
1839 GLint reference,
1840 GLuint mask,
1841 GLenum coverMode)
1842{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001843 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001844 if (!pathObj)
1845 return;
1846
1847 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1848 syncRendererState();
1849
1850 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1851}
1852
Sami Väisänend59ca052016-06-21 16:10:00 +03001853void Context::coverFillPathInstanced(GLsizei numPaths,
1854 GLenum pathNameType,
1855 const void *paths,
1856 GLuint pathBase,
1857 GLenum coverMode,
1858 GLenum transformType,
1859 const GLfloat *transformValues)
1860{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001861 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001862
1863 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1864 syncRendererState();
1865
1866 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1867}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001868
Sami Väisänend59ca052016-06-21 16:10:00 +03001869void Context::coverStrokePathInstanced(GLsizei numPaths,
1870 GLenum pathNameType,
1871 const void *paths,
1872 GLuint pathBase,
1873 GLenum coverMode,
1874 GLenum transformType,
1875 const GLfloat *transformValues)
1876{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001877 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001878
1879 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1880 syncRendererState();
1881
1882 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1883 transformValues);
1884}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001885
Sami Väisänend59ca052016-06-21 16:10:00 +03001886void Context::stencilFillPathInstanced(GLsizei numPaths,
1887 GLenum pathNameType,
1888 const void *paths,
1889 GLuint pathBase,
1890 GLenum fillMode,
1891 GLuint mask,
1892 GLenum transformType,
1893 const GLfloat *transformValues)
1894{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001895 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001896
1897 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1898 syncRendererState();
1899
1900 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1901 transformValues);
1902}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001903
Sami Väisänend59ca052016-06-21 16:10:00 +03001904void Context::stencilStrokePathInstanced(GLsizei numPaths,
1905 GLenum pathNameType,
1906 const void *paths,
1907 GLuint pathBase,
1908 GLint reference,
1909 GLuint mask,
1910 GLenum transformType,
1911 const GLfloat *transformValues)
1912{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001913 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001914
1915 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1916 syncRendererState();
1917
1918 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1919 transformValues);
1920}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001921
Sami Väisänend59ca052016-06-21 16:10:00 +03001922void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1923 GLenum pathNameType,
1924 const void *paths,
1925 GLuint pathBase,
1926 GLenum fillMode,
1927 GLuint mask,
1928 GLenum coverMode,
1929 GLenum transformType,
1930 const GLfloat *transformValues)
1931{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001932 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001933
1934 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1935 syncRendererState();
1936
1937 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1938 transformType, transformValues);
1939}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001940
Sami Väisänend59ca052016-06-21 16:10:00 +03001941void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1942 GLenum pathNameType,
1943 const void *paths,
1944 GLuint pathBase,
1945 GLint reference,
1946 GLuint mask,
1947 GLenum coverMode,
1948 GLenum transformType,
1949 const GLfloat *transformValues)
1950{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001951 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001952
1953 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1954 syncRendererState();
1955
1956 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1957 transformType, transformValues);
1958}
1959
Sami Väisänen46eaa942016-06-29 10:26:37 +03001960void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1961{
1962 auto *programObject = getProgram(program);
1963
1964 programObject->bindFragmentInputLocation(location, name);
1965}
1966
1967void Context::programPathFragmentInputGen(GLuint program,
1968 GLint location,
1969 GLenum genMode,
1970 GLint components,
1971 const GLfloat *coeffs)
1972{
1973 auto *programObject = getProgram(program);
1974
1975 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1976}
1977
Jamie Madill437fa652016-05-03 15:13:24 -04001978void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001979{
Geoff Langda5777c2014-07-11 09:52:58 -04001980 if (error.isError())
1981 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001982 GLenum code = error.getCode();
1983 mErrors.insert(code);
1984 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1985 {
1986 markContextLost();
1987 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001988
1989 if (!error.getMessage().empty())
1990 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001991 auto *debug = &mGLState.getDebug();
1992 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1993 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001994 }
Geoff Langda5777c2014-07-11 09:52:58 -04001995 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001996}
1997
1998// Get one of the recorded errors and clear its flag, if any.
1999// [OpenGL ES 2.0.24] section 2.5 page 13.
2000GLenum Context::getError()
2001{
Geoff Langda5777c2014-07-11 09:52:58 -04002002 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002003 {
Geoff Langda5777c2014-07-11 09:52:58 -04002004 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002005 }
Geoff Langda5777c2014-07-11 09:52:58 -04002006 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002007 {
Geoff Langda5777c2014-07-11 09:52:58 -04002008 GLenum error = *mErrors.begin();
2009 mErrors.erase(mErrors.begin());
2010 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002011 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002012}
2013
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002014// NOTE: this function should not assume that this context is current!
2015void Context::markContextLost()
2016{
2017 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002018 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002019 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002020 mContextLostForced = true;
2021 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002022 mContextLost = true;
2023}
2024
2025bool Context::isContextLost()
2026{
2027 return mContextLost;
2028}
2029
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002030GLenum Context::getResetStatus()
2031{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002032 // Even if the application doesn't want to know about resets, we want to know
2033 // as it will allow us to skip all the calls.
2034 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002035 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002036 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002037 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002038 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002039 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002040
2041 // EXT_robustness, section 2.6: If the reset notification behavior is
2042 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2043 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2044 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002045 }
2046
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002047 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2048 // status should be returned at least once, and GL_NO_ERROR should be returned
2049 // once the device has finished resetting.
2050 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002051 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002052 ASSERT(mResetStatus == GL_NO_ERROR);
2053 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002054
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002055 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002056 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002057 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002058 }
2059 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002060 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002061 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002062 // If markContextLost was used to mark the context lost then
2063 // assume that is not recoverable, and continue to report the
2064 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002065 mResetStatus = mImplementation->getResetStatus();
2066 }
Jamie Madill893ab082014-05-16 16:56:10 -04002067
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002068 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002069}
2070
2071bool Context::isResetNotificationEnabled()
2072{
2073 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2074}
2075
Corentin Walleze3b10e82015-05-20 11:06:25 -04002076const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002077{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002078 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002079}
2080
2081EGLenum Context::getClientType() const
2082{
2083 return mClientType;
2084}
2085
2086EGLenum Context::getRenderBuffer() const
2087{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002088 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2089 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002090 {
2091 return EGL_NONE;
2092 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002093
2094 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2095 ASSERT(backAttachment != nullptr);
2096 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002097}
2098
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002099VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002100{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002101 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002102 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2103 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002104 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002105 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2106 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002107
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002108 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002109 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002110
2111 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002112}
2113
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002114TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002115{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002116 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002117 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2118 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002119 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002120 transformFeedback =
2121 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002122 transformFeedback->addRef();
2123 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002124 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002125
2126 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002127}
2128
2129bool Context::isVertexArrayGenerated(GLuint vertexArray)
2130{
Geoff Langf41a7152016-09-19 15:11:17 -04002131 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002132 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2133}
2134
2135bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2136{
Geoff Langf41a7152016-09-19 15:11:17 -04002137 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002138 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2139}
2140
Shannon Woods53a94a82014-06-24 15:20:36 -04002141void Context::detachTexture(GLuint texture)
2142{
2143 // Simple pass-through to State's detachTexture method, as textures do not require
2144 // allocation map management either here or in the resource manager at detach time.
2145 // Zero textures are held by the Context, and we don't attempt to request them from
2146 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002147 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002148}
2149
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002150void Context::detachBuffer(GLuint buffer)
2151{
Yuly Novikov5807a532015-12-03 13:01:22 -05002152 // Simple pass-through to State's detachBuffer method, since
2153 // only buffer attachments to container objects that are bound to the current context
2154 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002155
Yuly Novikov5807a532015-12-03 13:01:22 -05002156 // [OpenGL ES 3.2] section 5.1.2 page 45:
2157 // Attachments to unbound container objects, such as
2158 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2159 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002160 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002161}
2162
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002163void Context::detachFramebuffer(GLuint framebuffer)
2164{
Shannon Woods53a94a82014-06-24 15:20:36 -04002165 // Framebuffer detachment is handled by Context, because 0 is a valid
2166 // Framebuffer object, and a pointer to it must be passed from Context
2167 // to State at binding time.
2168
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002169 // [OpenGL ES 2.0.24] section 4.4 page 107:
2170 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2171 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2172
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002173 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002174 {
2175 bindReadFramebuffer(0);
2176 }
2177
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002178 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002179 {
2180 bindDrawFramebuffer(0);
2181 }
2182}
2183
2184void Context::detachRenderbuffer(GLuint renderbuffer)
2185{
Jamie Madilla02315b2017-02-23 14:14:47 -05002186 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002187}
2188
Jamie Madill57a89722013-07-02 11:57:03 -04002189void Context::detachVertexArray(GLuint vertexArray)
2190{
Jamie Madill77a72f62015-04-14 11:18:32 -04002191 // Vertex array detachment is handled by Context, because 0 is a valid
2192 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002193 // binding time.
2194
Jamie Madill57a89722013-07-02 11:57:03 -04002195 // [OpenGL ES 3.0.2] section 2.10 page 43:
2196 // If a vertex array object that is currently bound is deleted, the binding
2197 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002198 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002199 {
2200 bindVertexArray(0);
2201 }
2202}
2203
Geoff Langc8058452014-02-03 12:04:11 -05002204void Context::detachTransformFeedback(GLuint transformFeedback)
2205{
Corentin Walleza2257da2016-04-19 16:43:12 -04002206 // Transform feedback detachment is handled by Context, because 0 is a valid
2207 // transform feedback, and a pointer to it must be passed from Context to State at
2208 // binding time.
2209
2210 // The OpenGL specification doesn't mention what should happen when the currently bound
2211 // transform feedback object is deleted. Since it is a container object, we treat it like
2212 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002213 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002214 {
2215 bindTransformFeedback(0);
2216 }
Geoff Langc8058452014-02-03 12:04:11 -05002217}
2218
Jamie Madilldc356042013-07-19 16:36:57 -04002219void Context::detachSampler(GLuint sampler)
2220{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002221 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002222}
2223
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002224void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2225{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002226 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002227}
2228
Jamie Madille29d1672013-07-19 16:36:57 -04002229void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2230{
Geoff Langc1984ed2016-10-07 12:41:00 -04002231 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002232 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002233 SetSamplerParameteri(samplerObject, pname, param);
2234}
Jamie Madille29d1672013-07-19 16:36:57 -04002235
Geoff Langc1984ed2016-10-07 12:41:00 -04002236void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2237{
2238 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002239 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002240 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002241}
2242
2243void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2244{
Geoff Langc1984ed2016-10-07 12:41:00 -04002245 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002246 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002247 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002248}
2249
Geoff Langc1984ed2016-10-07 12:41:00 -04002250void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002251{
Geoff Langc1984ed2016-10-07 12:41:00 -04002252 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002253 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002254 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002255}
2256
Geoff Langc1984ed2016-10-07 12:41:00 -04002257void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002258{
Geoff Langc1984ed2016-10-07 12:41:00 -04002259 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002260 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002261 QuerySamplerParameteriv(samplerObject, pname, params);
2262}
Jamie Madill9675b802013-07-19 16:36:59 -04002263
Geoff Langc1984ed2016-10-07 12:41:00 -04002264void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2265{
2266 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002267 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002268 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002269}
2270
Olli Etuahof0fee072016-03-30 15:11:58 +03002271void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2272{
2273 gl::Program *programObject = getProgram(program);
2274 ASSERT(programObject != nullptr);
2275
2276 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2277 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2278}
2279
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002280void Context::initRendererString()
2281{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002282 std::ostringstream rendererString;
2283 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002284 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002285 rendererString << ")";
2286
Geoff Langcec35902014-04-16 10:52:36 -04002287 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002288}
2289
Geoff Langc339c4e2016-11-29 10:37:36 -05002290void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002291{
Geoff Langc339c4e2016-11-29 10:37:36 -05002292 const Version &clientVersion = getClientVersion();
2293
2294 std::ostringstream versionString;
2295 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2296 << ANGLE_VERSION_STRING << ")";
2297 mVersionString = MakeStaticString(versionString.str());
2298
2299 std::ostringstream shadingLanguageVersionString;
2300 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2301 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2302 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2303 << ")";
2304 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002305}
2306
Geoff Langcec35902014-04-16 10:52:36 -04002307void Context::initExtensionStrings()
2308{
Geoff Langc339c4e2016-11-29 10:37:36 -05002309 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2310 std::ostringstream combinedStringStream;
2311 std::copy(strings.begin(), strings.end(),
2312 std::ostream_iterator<const char *>(combinedStringStream, " "));
2313 return MakeStaticString(combinedStringStream.str());
2314 };
2315
2316 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002317 for (const auto &extensionString : mExtensions.getStrings())
2318 {
2319 mExtensionStrings.push_back(MakeStaticString(extensionString));
2320 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002321 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002322
Bryan Bernhart58806562017-01-05 13:09:31 -08002323 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2324
Geoff Langc339c4e2016-11-29 10:37:36 -05002325 mRequestableExtensionStrings.clear();
2326 for (const auto &extensionInfo : GetExtensionInfoMap())
2327 {
2328 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002329 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2330 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002331 {
2332 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2333 }
2334 }
2335 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002336}
2337
Geoff Langc339c4e2016-11-29 10:37:36 -05002338const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002339{
Geoff Langc339c4e2016-11-29 10:37:36 -05002340 switch (name)
2341 {
2342 case GL_VENDOR:
2343 return reinterpret_cast<const GLubyte *>("Google Inc.");
2344
2345 case GL_RENDERER:
2346 return reinterpret_cast<const GLubyte *>(mRendererString);
2347
2348 case GL_VERSION:
2349 return reinterpret_cast<const GLubyte *>(mVersionString);
2350
2351 case GL_SHADING_LANGUAGE_VERSION:
2352 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2353
2354 case GL_EXTENSIONS:
2355 return reinterpret_cast<const GLubyte *>(mExtensionString);
2356
2357 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2358 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2359
2360 default:
2361 UNREACHABLE();
2362 return nullptr;
2363 }
Geoff Langcec35902014-04-16 10:52:36 -04002364}
2365
Geoff Langc339c4e2016-11-29 10:37:36 -05002366const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002367{
Geoff Langc339c4e2016-11-29 10:37:36 -05002368 switch (name)
2369 {
2370 case GL_EXTENSIONS:
2371 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2372
2373 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2374 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2375
2376 default:
2377 UNREACHABLE();
2378 return nullptr;
2379 }
Geoff Langcec35902014-04-16 10:52:36 -04002380}
2381
2382size_t Context::getExtensionStringCount() const
2383{
2384 return mExtensionStrings.size();
2385}
2386
Geoff Langc339c4e2016-11-29 10:37:36 -05002387void Context::requestExtension(const char *name)
2388{
2389 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2390 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2391 const auto &extension = extensionInfos.at(name);
2392 ASSERT(extension.Requestable);
2393
2394 if (mExtensions.*(extension.ExtensionsMember))
2395 {
2396 // Extension already enabled
2397 return;
2398 }
2399
2400 mExtensions.*(extension.ExtensionsMember) = true;
2401 updateCaps();
2402 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002403
2404 // Re-create the compiler with the requested extensions enabled.
2405 SafeDelete(mCompiler);
2406 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002407}
2408
2409size_t Context::getRequestableExtensionStringCount() const
2410{
2411 return mRequestableExtensionStrings.size();
2412}
2413
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002414void Context::beginTransformFeedback(GLenum primitiveMode)
2415{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002416 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002417 ASSERT(transformFeedback != nullptr);
2418 ASSERT(!transformFeedback->isPaused());
2419
Jamie Madill6c1f6712017-02-14 19:08:04 -05002420 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002421}
2422
2423bool Context::hasActiveTransformFeedback(GLuint program) const
2424{
2425 for (auto pair : mTransformFeedbackMap)
2426 {
2427 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2428 {
2429 return true;
2430 }
2431 }
2432 return false;
2433}
2434
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002435void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002436{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002437 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002438
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002439 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002440
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002441 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002442
Geoff Langeb66a6e2016-10-31 13:06:12 -04002443 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002444 {
2445 // Disable ES3+ extensions
2446 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002447 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002448 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002449 }
2450
Geoff Langeb66a6e2016-10-31 13:06:12 -04002451 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002452 {
2453 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2454 //mExtensions.sRGB = false;
2455 }
2456
Jamie Madill00ed7a12016-05-19 13:13:38 -04002457 // Some extensions are always available because they are implemented in the GL layer.
2458 mExtensions.bindUniformLocation = true;
2459 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002460 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002461 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002462 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002463
2464 // Enable the no error extension if the context was created with the flag.
2465 mExtensions.noError = mSkipValidation;
2466
Corentin Wallezccab69d2017-01-27 16:57:15 -05002467 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002468 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002469
Geoff Lang70d0f492015-12-10 17:45:46 -05002470 // Explicitly enable GL_KHR_debug
2471 mExtensions.debug = true;
2472 mExtensions.maxDebugMessageLength = 1024;
2473 mExtensions.maxDebugLoggedMessages = 1024;
2474 mExtensions.maxDebugGroupStackDepth = 1024;
2475 mExtensions.maxLabelLength = 1024;
2476
Geoff Langff5b2d52016-09-07 11:32:23 -04002477 // Explicitly enable GL_ANGLE_robust_client_memory
2478 mExtensions.robustClientMemory = true;
2479
Geoff Lang301d1612014-07-09 10:34:37 -04002480 // Apply implementation limits
2481 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002482 mCaps.maxVertexAttribBindings =
2483 getClientVersion() < ES_3_1
2484 ? mCaps.maxVertexAttributes
2485 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2486
Geoff Lang301d1612014-07-09 10:34:37 -04002487 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2488 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2489
2490 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002491
Geoff Langc287ea62016-09-16 14:46:51 -04002492 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002493 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002494 for (const auto &extensionInfo : GetExtensionInfoMap())
2495 {
2496 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002497 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002498 {
2499 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2500 }
2501 }
2502
2503 // Generate texture caps
2504 updateCaps();
2505}
2506
2507void Context::updateCaps()
2508{
Geoff Lang900013c2014-07-07 11:32:19 -04002509 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002510 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002511
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002512 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002513 {
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002514 GLenum format = capsIt.first;
2515 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002516
Geoff Lang5d601382014-07-22 15:14:06 -04002517 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002518
Geoff Lang0d8b7242015-09-09 14:56:53 -04002519 // Update the format caps based on the client version and extensions.
2520 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2521 // ES3.
2522 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002523 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002524 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002525 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002526 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002527 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002528
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002529 // OpenGL ES does not support multisampling with non-rendererable formats
2530 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2531 if (!formatInfo.renderSupport ||
2532 (getClientVersion() < ES_3_1 &&
2533 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002534 {
Geoff Langd87878e2014-09-19 15:42:59 -04002535 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002536 }
Geoff Langd87878e2014-09-19 15:42:59 -04002537
2538 if (formatCaps.texturable && formatInfo.compressed)
2539 {
2540 mCaps.compressedTextureFormats.push_back(format);
2541 }
2542
2543 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002544 }
2545}
2546
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002547void Context::initWorkarounds()
2548{
2549 // Lose the context upon out of memory error if the application is
2550 // expecting to watch for those events.
2551 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2552}
2553
Jamie Madill1b94d432015-08-07 13:23:23 -04002554void Context::syncRendererState()
2555{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002556 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002557 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002558 mGLState.clearDirtyBits();
2559 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002560}
2561
Jamie Madillad9f24e2016-02-12 09:27:24 -05002562void Context::syncRendererState(const State::DirtyBits &bitMask,
2563 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002564{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002565 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002566 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002567 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002568
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002569 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002570}
Jamie Madillc29968b2016-01-20 11:17:23 -05002571
2572void Context::blitFramebuffer(GLint srcX0,
2573 GLint srcY0,
2574 GLint srcX1,
2575 GLint srcY1,
2576 GLint dstX0,
2577 GLint dstY0,
2578 GLint dstX1,
2579 GLint dstY1,
2580 GLbitfield mask,
2581 GLenum filter)
2582{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002583 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002584 ASSERT(drawFramebuffer);
2585
2586 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2587 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2588
Jamie Madillad9f24e2016-02-12 09:27:24 -05002589 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002590
Jamie Madill8415b5f2016-04-26 13:41:39 -04002591 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002592}
Jamie Madillc29968b2016-01-20 11:17:23 -05002593
2594void Context::clear(GLbitfield mask)
2595{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002596 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002597 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002598}
2599
2600void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2601{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002602 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002603 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2604 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002605}
2606
2607void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2608{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002609 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002610 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2611 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002612}
2613
2614void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2615{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002616 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002617 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2618 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002619}
2620
2621void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2622{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002623 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002624 ASSERT(framebufferObject);
2625
2626 // If a buffer is not present, the clear has no effect
2627 if (framebufferObject->getDepthbuffer() == nullptr &&
2628 framebufferObject->getStencilbuffer() == nullptr)
2629 {
2630 return;
2631 }
2632
Jamie Madillad9f24e2016-02-12 09:27:24 -05002633 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002634 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2635 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002636}
2637
2638void Context::readPixels(GLint x,
2639 GLint y,
2640 GLsizei width,
2641 GLsizei height,
2642 GLenum format,
2643 GLenum type,
2644 GLvoid *pixels)
2645{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002646 if (width == 0 || height == 0)
2647 {
2648 return;
2649 }
2650
Jamie Madillad9f24e2016-02-12 09:27:24 -05002651 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002652
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002653 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002654 ASSERT(framebufferObject);
2655
2656 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002657 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002658}
2659
2660void Context::copyTexImage2D(GLenum target,
2661 GLint level,
2662 GLenum internalformat,
2663 GLint x,
2664 GLint y,
2665 GLsizei width,
2666 GLsizei height,
2667 GLint border)
2668{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002669 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002670 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002671
Jamie Madillc29968b2016-01-20 11:17:23 -05002672 Rectangle sourceArea(x, y, width, height);
2673
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002674 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002675 Texture *texture =
2676 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002677 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002678}
2679
2680void Context::copyTexSubImage2D(GLenum target,
2681 GLint level,
2682 GLint xoffset,
2683 GLint yoffset,
2684 GLint x,
2685 GLint y,
2686 GLsizei width,
2687 GLsizei height)
2688{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002689 if (width == 0 || height == 0)
2690 {
2691 return;
2692 }
2693
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002694 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002695 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002696
Jamie Madillc29968b2016-01-20 11:17:23 -05002697 Offset destOffset(xoffset, yoffset, 0);
2698 Rectangle sourceArea(x, y, width, height);
2699
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002700 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002701 Texture *texture =
2702 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002703 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002704}
2705
2706void Context::copyTexSubImage3D(GLenum target,
2707 GLint level,
2708 GLint xoffset,
2709 GLint yoffset,
2710 GLint zoffset,
2711 GLint x,
2712 GLint y,
2713 GLsizei width,
2714 GLsizei height)
2715{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002716 if (width == 0 || height == 0)
2717 {
2718 return;
2719 }
2720
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002721 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002722 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002723
Jamie Madillc29968b2016-01-20 11:17:23 -05002724 Offset destOffset(xoffset, yoffset, zoffset);
2725 Rectangle sourceArea(x, y, width, height);
2726
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002727 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002728 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002729 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002730}
2731
2732void Context::framebufferTexture2D(GLenum target,
2733 GLenum attachment,
2734 GLenum textarget,
2735 GLuint texture,
2736 GLint level)
2737{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002738 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002739 ASSERT(framebuffer);
2740
2741 if (texture != 0)
2742 {
2743 Texture *textureObj = getTexture(texture);
2744
2745 ImageIndex index = ImageIndex::MakeInvalid();
2746
2747 if (textarget == GL_TEXTURE_2D)
2748 {
2749 index = ImageIndex::Make2D(level);
2750 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002751 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2752 {
2753 ASSERT(level == 0);
2754 index = ImageIndex::Make2DMultisample();
2755 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002756 else
2757 {
2758 ASSERT(IsCubeMapTextureTarget(textarget));
2759 index = ImageIndex::MakeCube(textarget, level);
2760 }
2761
Jamie Madilla02315b2017-02-23 14:14:47 -05002762 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002763 }
2764 else
2765 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002766 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002767 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002768
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002769 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002770}
2771
2772void Context::framebufferRenderbuffer(GLenum target,
2773 GLenum attachment,
2774 GLenum renderbuffertarget,
2775 GLuint renderbuffer)
2776{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002777 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002778 ASSERT(framebuffer);
2779
2780 if (renderbuffer != 0)
2781 {
2782 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002783
2784 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002785 renderbufferObject);
2786 }
2787 else
2788 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002789 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002790 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002791
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002792 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002793}
2794
2795void Context::framebufferTextureLayer(GLenum target,
2796 GLenum attachment,
2797 GLuint texture,
2798 GLint level,
2799 GLint layer)
2800{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002801 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002802 ASSERT(framebuffer);
2803
2804 if (texture != 0)
2805 {
2806 Texture *textureObject = getTexture(texture);
2807
2808 ImageIndex index = ImageIndex::MakeInvalid();
2809
2810 if (textureObject->getTarget() == GL_TEXTURE_3D)
2811 {
2812 index = ImageIndex::Make3D(level, layer);
2813 }
2814 else
2815 {
2816 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2817 index = ImageIndex::Make2DArray(level, layer);
2818 }
2819
Jamie Madilla02315b2017-02-23 14:14:47 -05002820 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002821 }
2822 else
2823 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002824 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002825 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002826
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002827 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002828}
2829
2830void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2831{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002832 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002833 ASSERT(framebuffer);
2834 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002835 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002836}
2837
2838void Context::readBuffer(GLenum mode)
2839{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002840 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002841 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002842 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002843}
2844
2845void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2846{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002847 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002848 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002849
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002850 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002851 ASSERT(framebuffer);
2852
2853 // The specification isn't clear what should be done when the framebuffer isn't complete.
2854 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002855 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002856}
2857
2858void Context::invalidateFramebuffer(GLenum target,
2859 GLsizei numAttachments,
2860 const GLenum *attachments)
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 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002874}
2875
2876void Context::invalidateSubFramebuffer(GLenum target,
2877 GLsizei numAttachments,
2878 const GLenum *attachments,
2879 GLint x,
2880 GLint y,
2881 GLsizei width,
2882 GLsizei height)
2883{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002884 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002885 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002886
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002887 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002888 ASSERT(framebuffer);
2889
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002890 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002891 {
Jamie Madill437fa652016-05-03 15:13:24 -04002892 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002893 }
Jamie Madill437fa652016-05-03 15:13:24 -04002894
2895 Rectangle area(x, y, width, height);
2896 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002897}
2898
Jamie Madill73a84962016-02-12 09:27:23 -05002899void Context::texImage2D(GLenum target,
2900 GLint level,
2901 GLint internalformat,
2902 GLsizei width,
2903 GLsizei height,
2904 GLint border,
2905 GLenum format,
2906 GLenum type,
2907 const GLvoid *pixels)
2908{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002909 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002910
2911 Extents size(width, height, 1);
2912 Texture *texture =
2913 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002914 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2915 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002916}
2917
2918void Context::texImage3D(GLenum target,
2919 GLint level,
2920 GLint internalformat,
2921 GLsizei width,
2922 GLsizei height,
2923 GLsizei depth,
2924 GLint border,
2925 GLenum format,
2926 GLenum type,
2927 const GLvoid *pixels)
2928{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002929 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002930
2931 Extents size(width, height, depth);
2932 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002933 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2934 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002935}
2936
2937void Context::texSubImage2D(GLenum target,
2938 GLint level,
2939 GLint xoffset,
2940 GLint yoffset,
2941 GLsizei width,
2942 GLsizei height,
2943 GLenum format,
2944 GLenum type,
2945 const GLvoid *pixels)
2946{
2947 // Zero sized uploads are valid but no-ops
2948 if (width == 0 || height == 0)
2949 {
2950 return;
2951 }
2952
Jamie Madillad9f24e2016-02-12 09:27:24 -05002953 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002954
2955 Box area(xoffset, yoffset, 0, width, height, 1);
2956 Texture *texture =
2957 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002958 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2959 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002960}
2961
2962void Context::texSubImage3D(GLenum target,
2963 GLint level,
2964 GLint xoffset,
2965 GLint yoffset,
2966 GLint zoffset,
2967 GLsizei width,
2968 GLsizei height,
2969 GLsizei depth,
2970 GLenum format,
2971 GLenum type,
2972 const GLvoid *pixels)
2973{
2974 // Zero sized uploads are valid but no-ops
2975 if (width == 0 || height == 0 || depth == 0)
2976 {
2977 return;
2978 }
2979
Jamie Madillad9f24e2016-02-12 09:27:24 -05002980 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002981
2982 Box area(xoffset, yoffset, zoffset, width, height, depth);
2983 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002984 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2985 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002986}
2987
2988void Context::compressedTexImage2D(GLenum target,
2989 GLint level,
2990 GLenum internalformat,
2991 GLsizei width,
2992 GLsizei height,
2993 GLint border,
2994 GLsizei imageSize,
2995 const GLvoid *data)
2996{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002997 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002998
2999 Extents size(width, height, 1);
3000 Texture *texture =
3001 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003002 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003003 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003004 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003005}
3006
3007void Context::compressedTexImage3D(GLenum target,
3008 GLint level,
3009 GLenum internalformat,
3010 GLsizei width,
3011 GLsizei height,
3012 GLsizei depth,
3013 GLint border,
3014 GLsizei imageSize,
3015 const GLvoid *data)
3016{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003017 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003018
3019 Extents size(width, height, depth);
3020 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003021 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003022 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003023 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003024}
3025
3026void Context::compressedTexSubImage2D(GLenum target,
3027 GLint level,
3028 GLint xoffset,
3029 GLint yoffset,
3030 GLsizei width,
3031 GLsizei height,
3032 GLenum format,
3033 GLsizei imageSize,
3034 const GLvoid *data)
3035{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003036 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003037
3038 Box area(xoffset, yoffset, 0, width, height, 1);
3039 Texture *texture =
3040 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003041 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003042 format, imageSize,
3043 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003044}
3045
3046void Context::compressedTexSubImage3D(GLenum target,
3047 GLint level,
3048 GLint xoffset,
3049 GLint yoffset,
3050 GLint zoffset,
3051 GLsizei width,
3052 GLsizei height,
3053 GLsizei depth,
3054 GLenum format,
3055 GLsizei imageSize,
3056 const GLvoid *data)
3057{
3058 // Zero sized uploads are valid but no-ops
3059 if (width == 0 || height == 0)
3060 {
3061 return;
3062 }
3063
Jamie Madillad9f24e2016-02-12 09:27:24 -05003064 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003065
3066 Box area(xoffset, yoffset, zoffset, width, height, depth);
3067 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003068 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003069 format, imageSize,
3070 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003071}
3072
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003073void Context::generateMipmap(GLenum target)
3074{
3075 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003076 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003077}
3078
Geoff Lang97073d12016-04-20 10:42:34 -07003079void Context::copyTextureCHROMIUM(GLuint sourceId,
3080 GLuint destId,
3081 GLint internalFormat,
3082 GLenum destType,
3083 GLboolean unpackFlipY,
3084 GLboolean unpackPremultiplyAlpha,
3085 GLboolean unpackUnmultiplyAlpha)
3086{
3087 syncStateForTexImage();
3088
3089 gl::Texture *sourceTexture = getTexture(sourceId);
3090 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003091 handleError(destTexture->copyTexture(this, internalFormat, destType, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003092 unpackPremultiplyAlpha == GL_TRUE,
3093 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3094}
3095
3096void Context::copySubTextureCHROMIUM(GLuint sourceId,
3097 GLuint destId,
3098 GLint xoffset,
3099 GLint yoffset,
3100 GLint x,
3101 GLint y,
3102 GLsizei width,
3103 GLsizei height,
3104 GLboolean unpackFlipY,
3105 GLboolean unpackPremultiplyAlpha,
3106 GLboolean unpackUnmultiplyAlpha)
3107{
3108 // Zero sized copies are valid but no-ops
3109 if (width == 0 || height == 0)
3110 {
3111 return;
3112 }
3113
3114 syncStateForTexImage();
3115
3116 gl::Texture *sourceTexture = getTexture(sourceId);
3117 gl::Texture *destTexture = getTexture(destId);
3118 Offset offset(xoffset, yoffset, 0);
3119 Rectangle area(x, y, width, height);
Jamie Madill8897afa2017-02-06 17:17:23 -05003120 handleError(destTexture->copySubTexture(this, offset, area, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003121 unpackPremultiplyAlpha == GL_TRUE,
3122 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3123}
3124
Geoff Lang47110bf2016-04-20 11:13:22 -07003125void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3126{
3127 syncStateForTexImage();
3128
3129 gl::Texture *sourceTexture = getTexture(sourceId);
3130 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003131 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003132}
3133
Geoff Lang496c02d2016-10-20 11:38:11 -07003134void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003135{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003136 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003137 ASSERT(buffer);
3138
Geoff Lang496c02d2016-10-20 11:38:11 -07003139 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003140}
3141
3142GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3143{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003144 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003145 ASSERT(buffer);
3146
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003147 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003148 if (error.isError())
3149 {
Jamie Madill437fa652016-05-03 15:13:24 -04003150 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003151 return nullptr;
3152 }
3153
3154 return buffer->getMapPointer();
3155}
3156
3157GLboolean Context::unmapBuffer(GLenum target)
3158{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003159 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003160 ASSERT(buffer);
3161
3162 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003163 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003164 if (error.isError())
3165 {
Jamie Madill437fa652016-05-03 15:13:24 -04003166 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003167 return GL_FALSE;
3168 }
3169
3170 return result;
3171}
3172
3173GLvoid *Context::mapBufferRange(GLenum target,
3174 GLintptr offset,
3175 GLsizeiptr length,
3176 GLbitfield access)
3177{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003178 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003179 ASSERT(buffer);
3180
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003181 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003182 if (error.isError())
3183 {
Jamie Madill437fa652016-05-03 15:13:24 -04003184 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003185 return nullptr;
3186 }
3187
3188 return buffer->getMapPointer();
3189}
3190
3191void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3192{
3193 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3194}
3195
Jamie Madillad9f24e2016-02-12 09:27:24 -05003196void Context::syncStateForReadPixels()
3197{
3198 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3199}
3200
3201void Context::syncStateForTexImage()
3202{
3203 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3204}
3205
3206void Context::syncStateForClear()
3207{
3208 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3209}
3210
3211void Context::syncStateForBlit()
3212{
3213 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3214}
3215
Jamie Madillc20ab272016-06-09 07:20:46 -07003216void Context::activeTexture(GLenum texture)
3217{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003218 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003219}
3220
3221void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3222{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003223 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003224}
3225
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003226void Context::blendEquation(GLenum mode)
3227{
3228 mGLState.setBlendEquation(mode, mode);
3229}
3230
Jamie Madillc20ab272016-06-09 07:20:46 -07003231void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3232{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003233 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003234}
3235
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003236void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3237{
3238 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3239}
3240
Jamie Madillc20ab272016-06-09 07:20:46 -07003241void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3242{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003243 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003244}
3245
3246void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3247{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003248 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003249}
3250
3251void Context::clearDepthf(GLclampf depth)
3252{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003253 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003254}
3255
3256void Context::clearStencil(GLint s)
3257{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003258 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003259}
3260
3261void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3262{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003263 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003264}
3265
3266void Context::cullFace(GLenum mode)
3267{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003268 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003269}
3270
3271void Context::depthFunc(GLenum func)
3272{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003273 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003274}
3275
3276void Context::depthMask(GLboolean flag)
3277{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003278 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003279}
3280
3281void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3282{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003283 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003284}
3285
3286void Context::disable(GLenum cap)
3287{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003288 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003289}
3290
3291void Context::disableVertexAttribArray(GLuint index)
3292{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003293 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003294}
3295
3296void Context::enable(GLenum cap)
3297{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003298 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003299}
3300
3301void Context::enableVertexAttribArray(GLuint index)
3302{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003303 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003304}
3305
3306void Context::frontFace(GLenum mode)
3307{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003308 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003309}
3310
3311void Context::hint(GLenum target, GLenum mode)
3312{
3313 switch (target)
3314 {
3315 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003316 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003317 break;
3318
3319 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003320 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003321 break;
3322
3323 default:
3324 UNREACHABLE();
3325 return;
3326 }
3327}
3328
3329void Context::lineWidth(GLfloat width)
3330{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003331 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003332}
3333
3334void Context::pixelStorei(GLenum pname, GLint param)
3335{
3336 switch (pname)
3337 {
3338 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340 break;
3341
3342 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003343 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003344 break;
3345
3346 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003347 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003348 break;
3349
3350 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003351 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003352 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003353 break;
3354
3355 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003356 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003357 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003358 break;
3359
3360 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003361 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003362 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003363 break;
3364
3365 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003366 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003367 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003368 break;
3369
3370 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003371 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003372 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003373 break;
3374
3375 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003376 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003377 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003378 break;
3379
3380 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003381 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003382 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003383 break;
3384
3385 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003386 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003387 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003388 break;
3389
3390 default:
3391 UNREACHABLE();
3392 return;
3393 }
3394}
3395
3396void Context::polygonOffset(GLfloat factor, GLfloat units)
3397{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003398 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003399}
3400
3401void Context::sampleCoverage(GLclampf value, GLboolean invert)
3402{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003403 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003404}
3405
3406void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3407{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003408 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003409}
3410
3411void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3412{
3413 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3414 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003415 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003416 }
3417
3418 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3419 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003420 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003421 }
3422}
3423
3424void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3425{
3426 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3427 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003428 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003429 }
3430
3431 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3432 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003433 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003434 }
3435}
3436
3437void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3438{
3439 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3440 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003441 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003442 }
3443
3444 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3445 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003446 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003447 }
3448}
3449
3450void Context::vertexAttrib1f(GLuint index, GLfloat x)
3451{
3452 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003453 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003454}
3455
3456void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3457{
3458 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003460}
3461
3462void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3463{
3464 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003466}
3467
3468void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3469{
3470 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003471 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003472}
3473
3474void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3475{
3476 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003477 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003478}
3479
3480void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3481{
3482 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484}
3485
3486void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3487{
3488 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003489 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003490}
3491
3492void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3493{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003494 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003495}
3496
3497void Context::vertexAttribPointer(GLuint index,
3498 GLint size,
3499 GLenum type,
3500 GLboolean normalized,
3501 GLsizei stride,
3502 const GLvoid *ptr)
3503{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003504 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3505 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003506}
3507
3508void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3509{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003511}
3512
3513void Context::vertexAttribIPointer(GLuint index,
3514 GLint size,
3515 GLenum type,
3516 GLsizei stride,
3517 const GLvoid *pointer)
3518{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003519 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3520 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
3523void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3524{
3525 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003526 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003527}
3528
3529void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3530{
3531 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003532 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003533}
3534
3535void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003538}
3539
3540void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3541{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003542 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003543}
3544
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003545void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3546{
3547 const VertexAttribCurrentValueData &currentValues =
3548 getGLState().getVertexAttribCurrentValue(index);
3549 const VertexArray *vao = getGLState().getVertexArray();
3550 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3551 currentValues, pname, params);
3552}
3553
3554void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3555{
3556 const VertexAttribCurrentValueData &currentValues =
3557 getGLState().getVertexAttribCurrentValue(index);
3558 const VertexArray *vao = getGLState().getVertexArray();
3559 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3560 currentValues, pname, params);
3561}
3562
3563void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3564{
3565 const VertexAttribCurrentValueData &currentValues =
3566 getGLState().getVertexAttribCurrentValue(index);
3567 const VertexArray *vao = getGLState().getVertexArray();
3568 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3569 currentValues, pname, params);
3570}
3571
3572void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3573{
3574 const VertexAttribCurrentValueData &currentValues =
3575 getGLState().getVertexAttribCurrentValue(index);
3576 const VertexArray *vao = getGLState().getVertexArray();
3577 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3578 currentValues, pname, params);
3579}
3580
3581void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3582{
3583 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3584 QueryVertexAttribPointerv(attrib, pname, pointer);
3585}
3586
Jamie Madillc20ab272016-06-09 07:20:46 -07003587void Context::debugMessageControl(GLenum source,
3588 GLenum type,
3589 GLenum severity,
3590 GLsizei count,
3591 const GLuint *ids,
3592 GLboolean enabled)
3593{
3594 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003595 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3596 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003597}
3598
3599void Context::debugMessageInsert(GLenum source,
3600 GLenum type,
3601 GLuint id,
3602 GLenum severity,
3603 GLsizei length,
3604 const GLchar *buf)
3605{
3606 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003607 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003608}
3609
3610void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3611{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003612 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003613}
3614
3615GLuint Context::getDebugMessageLog(GLuint count,
3616 GLsizei bufSize,
3617 GLenum *sources,
3618 GLenum *types,
3619 GLuint *ids,
3620 GLenum *severities,
3621 GLsizei *lengths,
3622 GLchar *messageLog)
3623{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003624 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3625 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003626}
3627
3628void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3629{
3630 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003631 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003632}
3633
3634void Context::popDebugGroup()
3635{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003636 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003637}
3638
Jamie Madill29639852016-09-02 15:00:09 -04003639void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3640{
3641 Buffer *buffer = mGLState.getTargetBuffer(target);
3642 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003643 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003644}
3645
3646void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3647{
3648 if (data == nullptr)
3649 {
3650 return;
3651 }
3652
3653 Buffer *buffer = mGLState.getTargetBuffer(target);
3654 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003655 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003656}
3657
Jamie Madillef300b12016-10-07 15:12:09 -04003658void Context::attachShader(GLuint program, GLuint shader)
3659{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003660 auto programObject = mState.mShaderPrograms->getProgram(program);
3661 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003662 ASSERT(programObject && shaderObject);
3663 programObject->attachShader(shaderObject);
3664}
3665
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003666const Workarounds &Context::getWorkarounds() const
3667{
3668 return mWorkarounds;
3669}
3670
Jamie Madillb0817d12016-11-01 15:48:31 -04003671void Context::copyBufferSubData(GLenum readTarget,
3672 GLenum writeTarget,
3673 GLintptr readOffset,
3674 GLintptr writeOffset,
3675 GLsizeiptr size)
3676{
3677 // if size is zero, the copy is a successful no-op
3678 if (size == 0)
3679 {
3680 return;
3681 }
3682
3683 // TODO(jmadill): cache these.
3684 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3685 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3686
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003687 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003688}
3689
Jamie Madill01a80ee2016-11-07 12:06:18 -05003690void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3691{
3692 Program *programObject = getProgram(program);
3693 // TODO(jmadill): Re-use this from the validation if possible.
3694 ASSERT(programObject);
3695 programObject->bindAttributeLocation(index, name);
3696}
3697
3698void Context::bindBuffer(GLenum target, GLuint buffer)
3699{
3700 switch (target)
3701 {
3702 case GL_ARRAY_BUFFER:
3703 bindArrayBuffer(buffer);
3704 break;
3705 case GL_ELEMENT_ARRAY_BUFFER:
3706 bindElementArrayBuffer(buffer);
3707 break;
3708 case GL_COPY_READ_BUFFER:
3709 bindCopyReadBuffer(buffer);
3710 break;
3711 case GL_COPY_WRITE_BUFFER:
3712 bindCopyWriteBuffer(buffer);
3713 break;
3714 case GL_PIXEL_PACK_BUFFER:
3715 bindPixelPackBuffer(buffer);
3716 break;
3717 case GL_PIXEL_UNPACK_BUFFER:
3718 bindPixelUnpackBuffer(buffer);
3719 break;
3720 case GL_UNIFORM_BUFFER:
3721 bindGenericUniformBuffer(buffer);
3722 break;
3723 case GL_TRANSFORM_FEEDBACK_BUFFER:
3724 bindGenericTransformFeedbackBuffer(buffer);
3725 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003726 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003727 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003728 break;
3729 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003730 if (buffer != 0)
3731 {
3732 // Binding buffers to this binding point is not implemented yet.
3733 UNIMPLEMENTED();
3734 }
Geoff Lang3b573612016-10-31 14:08:10 -04003735 break;
3736 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003737 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003738 break;
3739 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003740 if (buffer != 0)
3741 {
3742 // Binding buffers to this binding point is not implemented yet.
3743 UNIMPLEMENTED();
3744 }
Geoff Lang3b573612016-10-31 14:08:10 -04003745 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003746
3747 default:
3748 UNREACHABLE();
3749 break;
3750 }
3751}
3752
Jiajia Qin6eafb042016-12-27 17:04:07 +08003753void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3754{
3755 bindBufferRange(target, index, buffer, 0, 0);
3756}
3757
3758void Context::bindBufferRange(GLenum target,
3759 GLuint index,
3760 GLuint buffer,
3761 GLintptr offset,
3762 GLsizeiptr size)
3763{
3764 switch (target)
3765 {
3766 case GL_TRANSFORM_FEEDBACK_BUFFER:
3767 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3768 bindGenericTransformFeedbackBuffer(buffer);
3769 break;
3770 case GL_UNIFORM_BUFFER:
3771 bindIndexedUniformBuffer(buffer, index, offset, size);
3772 bindGenericUniformBuffer(buffer);
3773 break;
3774 case GL_ATOMIC_COUNTER_BUFFER:
3775 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3776 bindGenericAtomicCounterBuffer(buffer);
3777 break;
3778 case GL_SHADER_STORAGE_BUFFER:
3779 if (buffer != 0)
3780 {
3781 // Binding buffers to this binding point is not implemented yet.
3782 UNIMPLEMENTED();
3783 }
3784 break;
3785 default:
3786 UNREACHABLE();
3787 break;
3788 }
3789}
3790
Jamie Madill01a80ee2016-11-07 12:06:18 -05003791void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3792{
3793 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3794 {
3795 bindReadFramebuffer(framebuffer);
3796 }
3797
3798 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3799 {
3800 bindDrawFramebuffer(framebuffer);
3801 }
3802}
3803
3804void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3805{
3806 ASSERT(target == GL_RENDERBUFFER);
3807 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003808 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003809 mGLState.setRenderbufferBinding(object);
3810}
3811
JiangYizhoubddc46b2016-12-09 09:50:51 +08003812void Context::texStorage2DMultisample(GLenum target,
3813 GLsizei samples,
3814 GLenum internalformat,
3815 GLsizei width,
3816 GLsizei height,
3817 GLboolean fixedsamplelocations)
3818{
3819 Extents size(width, height, 1);
3820 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003821 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003822 fixedsamplelocations));
3823}
3824
3825void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3826{
3827 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3828 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3829
3830 switch (pname)
3831 {
3832 case GL_SAMPLE_POSITION:
3833 handleError(framebuffer->getSamplePosition(index, val));
3834 break;
3835 default:
3836 UNREACHABLE();
3837 }
3838}
3839
Jamie Madille8fb6402017-02-14 17:56:40 -05003840void Context::renderbufferStorage(GLenum target,
3841 GLenum internalformat,
3842 GLsizei width,
3843 GLsizei height)
3844{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003845 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3846 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3847
Jamie Madille8fb6402017-02-14 17:56:40 -05003848 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003849 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003850}
3851
3852void Context::renderbufferStorageMultisample(GLenum target,
3853 GLsizei samples,
3854 GLenum internalformat,
3855 GLsizei width,
3856 GLsizei height)
3857{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003858 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3859 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05003860
3861 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003862 handleError(
3863 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003864}
3865
JiangYizhoue18e6392017-02-20 10:32:23 +08003866void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
3867{
3868 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3869 QueryFramebufferParameteriv(framebuffer, pname, params);
3870}
3871
3872void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
3873{
3874 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3875 SetFramebufferParameteri(framebuffer, pname, param);
3876}
3877
Jamie Madillc29968b2016-01-20 11:17:23 -05003878} // namespace gl