blob: 507618d82f13f900e5410aed74df5689442c14fb [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
Jamie Madille08a1d32017-03-07 17:24:06 -0500207bool GetRobustResourceInit(const egl::AttributeMap &attribs)
208{
209 return (attribs.get(EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
210}
211
Martin Radev9d901792016-07-15 15:58:58 +0300212std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
213{
214 std::string labelName;
215 if (label != nullptr)
216 {
217 size_t labelLength = length < 0 ? strlen(label) : length;
218 labelName = std::string(label, labelLength);
219 }
220 return labelName;
221}
222
223void GetObjectLabelBase(const std::string &objectLabel,
224 GLsizei bufSize,
225 GLsizei *length,
226 GLchar *label)
227{
228 size_t writeLength = objectLabel.length();
229 if (label != nullptr && bufSize > 0)
230 {
231 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
232 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
233 label[writeLength] = '\0';
234 }
235
236 if (length != nullptr)
237 {
238 *length = static_cast<GLsizei>(writeLength);
239 }
240}
241
Geoff Langf6db0982015-08-25 13:04:00 -0400242} // anonymous namespace
243
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000244namespace gl
245{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000246
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400247Context::Context(rx::EGLImplFactory *implFactory,
248 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400249 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500250 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500251 const egl::AttributeMap &attribs,
252 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300253
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500254 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500255 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500256 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700257 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500258 mCaps,
259 mTextureCaps,
260 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500261 mLimitations,
262 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700263 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500264 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400265 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500266 mClientType(EGL_OPENGL_ES_API),
267 mHasBeenCurrent(false),
268 mContextLost(false),
269 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700270 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500271 mResetStrategy(GetResetStrategy(attribs)),
272 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500273 mCurrentSurface(nullptr),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500274 mSurfacelessFramebuffer(nullptr),
275 mWebGLContext(GetWebGLContext(attribs))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276{
Geoff Lang077f20a2016-11-01 10:08:02 -0400277 if (mRobustAccess)
278 {
279 UNIMPLEMENTED();
280 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500282 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700283 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400284
Geoff Langeb66a6e2016-10-31 13:06:12 -0400285 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Jamie Madille08a1d32017-03-07 17:24:06 -0500286 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs),
287 GetRobustResourceInit(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100288
Shannon Woods53a94a82014-06-24 15:20:36 -0400289 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400290
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000291 // [OpenGL ES 2.0.24] section 3.7 page 83:
292 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
293 // and cube map texture state vectors respectively associated with them.
294 // In order that access to these initial textures not be lost, they are treated as texture
295 // objects all of whose names are 0.
296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500298 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400300 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500301 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400302
Geoff Langeb66a6e2016-10-31 13:06:12 -0400303 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400304 {
305 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500307 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400309 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500310 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400311 }
Geoff Lang3b573612016-10-31 14:08:10 -0400312 if (getClientVersion() >= Version(3, 1))
313 {
314 Texture *zeroTexture2DMultisample =
315 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
316 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800317
318 bindGenericAtomicCounterBuffer(0);
319 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
320 {
321 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
322 }
Geoff Lang3b573612016-10-31 14:08:10 -0400323 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000324
Ian Ewellbda75592016-04-18 17:25:54 -0400325 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
326 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400327 Texture *zeroTextureExternal =
328 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400329 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
330 }
331
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700332 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500333
Jamie Madill57a89722013-07-02 11:57:03 -0400334 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000335 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800336 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000337 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400338
Jamie Madill01a80ee2016-11-07 12:06:18 -0500339 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000340
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000341 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500342 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000343 {
344 bindIndexedUniformBuffer(0, i, 0, -1);
345 }
346
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000347 bindCopyReadBuffer(0);
348 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000349 bindPixelPackBuffer(0);
350 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000351
Geoff Langeb66a6e2016-10-31 13:06:12 -0400352 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400353 {
354 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
355 // In the initial state, a default transform feedback object is bound and treated as
356 // a transform feedback object with a name of zero. That object is bound any time
357 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400358 bindTransformFeedback(0);
359 }
Geoff Langc8058452014-02-03 12:04:11 -0500360
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700361 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500362
363 // Initialize dirty bit masks
364 // TODO(jmadill): additional ES3 state
365 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
366 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
367 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
368 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
369 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500372 // No dirty objects.
373
374 // Readpixels uses the pack state and read FBO
375 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
376 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
377 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
378 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
379 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500381 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
382
383 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
384 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
385 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
386 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
387 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
388 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
389 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
390 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
391 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
392 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
393 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
394 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
395
396 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
397 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700398 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500399 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
400 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400401
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400402 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000403}
404
Jamie Madill70ee0f62017-02-06 16:04:20 -0500405void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000406{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500407 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000408
Corentin Wallez80b24112015-08-25 16:41:57 -0400409 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000410 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400411 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000412 }
413
Corentin Wallez80b24112015-08-25 16:41:57 -0400414 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000415 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400416 if (query.second != nullptr)
417 {
418 query.second->release();
419 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420 }
421
Corentin Wallez80b24112015-08-25 16:41:57 -0400422 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400423 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400424 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400425 }
426
Corentin Wallez80b24112015-08-25 16:41:57 -0400427 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500428 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500429 if (transformFeedback.second != nullptr)
430 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500431 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500432 }
Geoff Langc8058452014-02-03 12:04:11 -0500433 }
434
Jamie Madilldedd7b92014-11-05 16:30:36 -0500435 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400436 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500437 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400438 }
439 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000440
Corentin Wallezccab69d2017-01-27 16:57:15 -0500441 SafeDelete(mSurfacelessFramebuffer);
442
Jamie Madill70ee0f62017-02-06 16:04:20 -0500443 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400444
Geoff Lang492a7e42014-11-05 13:27:06 -0500445 SafeDelete(mCompiler);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500446
447 mState.mBuffers->release(this);
448 mState.mShaderPrograms->release(this);
449 mState.mTextures->release(this);
450 mState.mRenderbuffers->release(this);
451 mState.mSamplers->release(this);
452 mState.mFenceSyncs->release(this);
453 mState.mPaths->release(this);
454 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000455}
456
Jamie Madill70ee0f62017-02-06 16:04:20 -0500457Context::~Context()
458{
459}
460
461void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000462{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463 if (!mHasBeenCurrent)
464 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000465 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500466 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400467 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000468
Corentin Wallezc295e512017-01-27 17:47:50 -0500469 int width = 0;
470 int height = 0;
471 if (surface != nullptr)
472 {
473 width = surface->getWidth();
474 height = surface->getHeight();
475 }
476
477 mGLState.setViewportParams(0, 0, width, height);
478 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000479
480 mHasBeenCurrent = true;
481 }
482
Jamie Madill1b94d432015-08-07 13:23:23 -0400483 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700484 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400485
Jamie Madill70ee0f62017-02-06 16:04:20 -0500486 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500487
488 Framebuffer *newDefault = nullptr;
489 if (surface != nullptr)
490 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500491 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500492 mCurrentSurface = surface;
493 newDefault = surface->getDefaultFramebuffer();
494 }
495 else
496 {
497 if (mSurfacelessFramebuffer == nullptr)
498 {
499 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
500 }
501
502 newDefault = mSurfacelessFramebuffer;
503 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000504
Corentin Wallez37c39792015-08-20 14:19:46 -0400505 // Update default framebuffer, the binding of the previous default
506 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400507 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700508 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400509 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700510 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400511 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700512 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400513 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700514 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400515 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500516 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400517 }
Ian Ewell292f0052016-02-04 10:37:32 -0500518
519 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700520 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000521}
522
Jamie Madill70ee0f62017-02-06 16:04:20 -0500523void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400524{
Corentin Wallez37c39792015-08-20 14:19:46 -0400525 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500526 Framebuffer *currentDefault = nullptr;
527 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400528 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500529 currentDefault = mCurrentSurface->getDefaultFramebuffer();
530 }
531 else if (mSurfacelessFramebuffer != nullptr)
532 {
533 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400534 }
535
Corentin Wallezc295e512017-01-27 17:47:50 -0500536 if (mGLState.getReadFramebuffer() == currentDefault)
537 {
538 mGLState.setReadFramebufferBinding(nullptr);
539 }
540 if (mGLState.getDrawFramebuffer() == currentDefault)
541 {
542 mGLState.setDrawFramebufferBinding(nullptr);
543 }
544 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
545
546 if (mCurrentSurface)
547 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500548 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500549 mCurrentSurface = nullptr;
550 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400551}
552
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000553GLuint Context::createBuffer()
554{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500555 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000556}
557
558GLuint Context::createProgram()
559{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500560 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000561}
562
563GLuint Context::createShader(GLenum type)
564{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500565 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000566}
567
568GLuint Context::createTexture()
569{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500570 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000571}
572
573GLuint Context::createRenderbuffer()
574{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500575 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000576}
577
Geoff Lang882033e2014-09-30 11:26:07 -0400578GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400579{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500580 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400581
Cooper Partind8e62a32015-01-29 15:21:25 -0800582 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400583}
584
Sami Väisänene45e53b2016-05-25 10:36:04 +0300585GLuint Context::createPaths(GLsizei range)
586{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500587 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300588 if (resultOrError.isError())
589 {
590 handleError(resultOrError.getError());
591 return 0;
592 }
593 return resultOrError.getResult();
594}
595
Jamie Madill57a89722013-07-02 11:57:03 -0400596GLuint Context::createVertexArray()
597{
Geoff Lang36167ab2015-12-07 10:27:14 -0500598 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
599 mVertexArrayMap[vertexArray] = nullptr;
600 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400601}
602
Jamie Madilldc356042013-07-19 16:36:57 -0400603GLuint Context::createSampler()
604{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500605 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400606}
607
Geoff Langc8058452014-02-03 12:04:11 -0500608GLuint Context::createTransformFeedback()
609{
Geoff Lang36167ab2015-12-07 10:27:14 -0500610 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
611 mTransformFeedbackMap[transformFeedback] = nullptr;
612 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500613}
614
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000615// Returns an unused framebuffer name
616GLuint Context::createFramebuffer()
617{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500618 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000619}
620
Jamie Madill33dc8432013-07-26 11:55:05 -0400621GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622{
Jamie Madill33dc8432013-07-26 11:55:05 -0400623 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000624
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400625 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626
627 return handle;
628}
629
630// Returns an unused query name
631GLuint Context::createQuery()
632{
633 GLuint handle = mQueryHandleAllocator.allocate();
634
635 mQueryMap[handle] = NULL;
636
637 return handle;
638}
639
640void Context::deleteBuffer(GLuint buffer)
641{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500642 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000643 {
644 detachBuffer(buffer);
645 }
Jamie Madill893ab082014-05-16 16:56:10 -0400646
Jamie Madill6c1f6712017-02-14 19:08:04 -0500647 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000648}
649
650void Context::deleteShader(GLuint shader)
651{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500652 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000653}
654
655void Context::deleteProgram(GLuint program)
656{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500657 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000658}
659
660void Context::deleteTexture(GLuint texture)
661{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500662 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000663 {
664 detachTexture(texture);
665 }
666
Jamie Madill6c1f6712017-02-14 19:08:04 -0500667 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000668}
669
670void Context::deleteRenderbuffer(GLuint renderbuffer)
671{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500672 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000673 {
674 detachRenderbuffer(renderbuffer);
675 }
Jamie Madill893ab082014-05-16 16:56:10 -0400676
Jamie Madill6c1f6712017-02-14 19:08:04 -0500677 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000678}
679
Jamie Madillcd055f82013-07-26 11:55:15 -0400680void Context::deleteFenceSync(GLsync fenceSync)
681{
682 // The spec specifies the underlying Fence object is not deleted until all current
683 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
684 // and since our API is currently designed for being called from a single thread, we can delete
685 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500686 mState.mFenceSyncs->deleteObject(this,
687 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400688}
689
Sami Väisänene45e53b2016-05-25 10:36:04 +0300690void Context::deletePaths(GLuint first, GLsizei range)
691{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500692 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300693}
694
695bool Context::hasPathData(GLuint path) const
696{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500697 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300698 if (pathObj == nullptr)
699 return false;
700
701 return pathObj->hasPathData();
702}
703
704bool Context::hasPath(GLuint path) const
705{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500706 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300707}
708
709void Context::setPathCommands(GLuint path,
710 GLsizei numCommands,
711 const GLubyte *commands,
712 GLsizei numCoords,
713 GLenum coordType,
714 const void *coords)
715{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500716 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300717
718 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
719}
720
721void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
722{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500723 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300724
725 switch (pname)
726 {
727 case GL_PATH_STROKE_WIDTH_CHROMIUM:
728 pathObj->setStrokeWidth(value);
729 break;
730 case GL_PATH_END_CAPS_CHROMIUM:
731 pathObj->setEndCaps(static_cast<GLenum>(value));
732 break;
733 case GL_PATH_JOIN_STYLE_CHROMIUM:
734 pathObj->setJoinStyle(static_cast<GLenum>(value));
735 break;
736 case GL_PATH_MITER_LIMIT_CHROMIUM:
737 pathObj->setMiterLimit(value);
738 break;
739 case GL_PATH_STROKE_BOUND_CHROMIUM:
740 pathObj->setStrokeBound(value);
741 break;
742 default:
743 UNREACHABLE();
744 break;
745 }
746}
747
748void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
749{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500750 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300751
752 switch (pname)
753 {
754 case GL_PATH_STROKE_WIDTH_CHROMIUM:
755 *value = pathObj->getStrokeWidth();
756 break;
757 case GL_PATH_END_CAPS_CHROMIUM:
758 *value = static_cast<GLfloat>(pathObj->getEndCaps());
759 break;
760 case GL_PATH_JOIN_STYLE_CHROMIUM:
761 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
762 break;
763 case GL_PATH_MITER_LIMIT_CHROMIUM:
764 *value = pathObj->getMiterLimit();
765 break;
766 case GL_PATH_STROKE_BOUND_CHROMIUM:
767 *value = pathObj->getStrokeBound();
768 break;
769 default:
770 UNREACHABLE();
771 break;
772 }
773}
774
775void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
776{
777 mGLState.setPathStencilFunc(func, ref, mask);
778}
779
Jamie Madill57a89722013-07-02 11:57:03 -0400780void Context::deleteVertexArray(GLuint vertexArray)
781{
Geoff Lang36167ab2015-12-07 10:27:14 -0500782 auto iter = mVertexArrayMap.find(vertexArray);
783 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000784 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500785 VertexArray *vertexArrayObject = iter->second;
786 if (vertexArrayObject != nullptr)
787 {
788 detachVertexArray(vertexArray);
789 delete vertexArrayObject;
790 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000791
Geoff Lang36167ab2015-12-07 10:27:14 -0500792 mVertexArrayMap.erase(iter);
793 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400794 }
795}
796
Jamie Madilldc356042013-07-19 16:36:57 -0400797void Context::deleteSampler(GLuint sampler)
798{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500799 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400800 {
801 detachSampler(sampler);
802 }
803
Jamie Madill6c1f6712017-02-14 19:08:04 -0500804 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400805}
806
Geoff Langc8058452014-02-03 12:04:11 -0500807void Context::deleteTransformFeedback(GLuint transformFeedback)
808{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500809 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500810 if (iter != mTransformFeedbackMap.end())
811 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500812 TransformFeedback *transformFeedbackObject = iter->second;
813 if (transformFeedbackObject != nullptr)
814 {
815 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500816 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500817 }
818
Geoff Lang50b3fe82015-12-08 14:49:12 +0000819 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500820 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500821 }
822}
823
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000824void Context::deleteFramebuffer(GLuint framebuffer)
825{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500826 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000827 {
828 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000829 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500830
Jamie Madill6c1f6712017-02-14 19:08:04 -0500831 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000832}
833
Jamie Madill33dc8432013-07-26 11:55:05 -0400834void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500836 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837
Jamie Madill33dc8432013-07-26 11:55:05 -0400838 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000839 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400840 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000841 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400842 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843 }
844}
845
846void Context::deleteQuery(GLuint query)
847{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500848 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849 if (queryObject != mQueryMap.end())
850 {
851 mQueryHandleAllocator.release(queryObject->first);
852 if (queryObject->second)
853 {
854 queryObject->second->release();
855 }
856 mQueryMap.erase(queryObject);
857 }
858}
859
Geoff Lang70d0f492015-12-10 17:45:46 -0500860Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000861{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500862 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000863}
864
Jamie Madill570f7c82014-07-03 10:38:54 -0400865Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000866{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500867 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000868}
869
Geoff Lang70d0f492015-12-10 17:45:46 -0500870Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000871{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500872 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000873}
874
Jamie Madillcd055f82013-07-26 11:55:15 -0400875FenceSync *Context::getFenceSync(GLsync handle) const
876{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500877 return mState.mFenceSyncs->getFenceSync(
878 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400879}
880
Jamie Madill57a89722013-07-02 11:57:03 -0400881VertexArray *Context::getVertexArray(GLuint handle) const
882{
883 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500884 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400885}
886
Jamie Madilldc356042013-07-19 16:36:57 -0400887Sampler *Context::getSampler(GLuint handle) const
888{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500889 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400890}
891
Geoff Langc8058452014-02-03 12:04:11 -0500892TransformFeedback *Context::getTransformFeedback(GLuint handle) const
893{
Geoff Lang36167ab2015-12-07 10:27:14 -0500894 auto iter = mTransformFeedbackMap.find(handle);
895 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500896}
897
Geoff Lang70d0f492015-12-10 17:45:46 -0500898LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
899{
900 switch (identifier)
901 {
902 case GL_BUFFER:
903 return getBuffer(name);
904 case GL_SHADER:
905 return getShader(name);
906 case GL_PROGRAM:
907 return getProgram(name);
908 case GL_VERTEX_ARRAY:
909 return getVertexArray(name);
910 case GL_QUERY:
911 return getQuery(name);
912 case GL_TRANSFORM_FEEDBACK:
913 return getTransformFeedback(name);
914 case GL_SAMPLER:
915 return getSampler(name);
916 case GL_TEXTURE:
917 return getTexture(name);
918 case GL_RENDERBUFFER:
919 return getRenderbuffer(name);
920 case GL_FRAMEBUFFER:
921 return getFramebuffer(name);
922 default:
923 UNREACHABLE();
924 return nullptr;
925 }
926}
927
928LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
929{
930 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
931}
932
Martin Radev9d901792016-07-15 15:58:58 +0300933void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
934{
935 LabeledObject *object = getLabeledObject(identifier, name);
936 ASSERT(object != nullptr);
937
938 std::string labelName = GetObjectLabelFromPointer(length, label);
939 object->setLabel(labelName);
940}
941
942void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
943{
944 LabeledObject *object = getLabeledObjectFromPtr(ptr);
945 ASSERT(object != nullptr);
946
947 std::string labelName = GetObjectLabelFromPointer(length, label);
948 object->setLabel(labelName);
949}
950
951void Context::getObjectLabel(GLenum identifier,
952 GLuint name,
953 GLsizei bufSize,
954 GLsizei *length,
955 GLchar *label) const
956{
957 LabeledObject *object = getLabeledObject(identifier, name);
958 ASSERT(object != nullptr);
959
960 const std::string &objectLabel = object->getLabel();
961 GetObjectLabelBase(objectLabel, bufSize, length, label);
962}
963
964void Context::getObjectPtrLabel(const void *ptr,
965 GLsizei bufSize,
966 GLsizei *length,
967 GLchar *label) const
968{
969 LabeledObject *object = getLabeledObjectFromPtr(ptr);
970 ASSERT(object != nullptr);
971
972 const std::string &objectLabel = object->getLabel();
973 GetObjectLabelBase(objectLabel, bufSize, length, label);
974}
975
Jamie Madilldc356042013-07-19 16:36:57 -0400976bool Context::isSampler(GLuint samplerName) const
977{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500978 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400979}
980
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500981void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000982{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500983 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700984 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000985}
986
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800987void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
988{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500989 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800990 mGLState.setDrawIndirectBufferBinding(buffer);
991}
992
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500993void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000994{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500995 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700996 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000997}
998
Jamie Madilldedd7b92014-11-05 16:30:36 -0500999void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001000{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001001 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001002
Jamie Madilldedd7b92014-11-05 16:30:36 -05001003 if (handle == 0)
1004 {
1005 texture = mZeroTextures[target].get();
1006 }
1007 else
1008 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001009 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001010 }
1011
1012 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001013 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001014}
1015
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001016void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001017{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001018 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1019 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001020 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001021}
1022
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001023void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001024{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001025 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1026 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001028}
1029
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001030void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001031{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001032 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001033 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001034}
1035
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001036void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001037{
Geoff Lang76b10c92014-09-05 16:28:14 -04001038 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001039 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001040 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001041 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001042}
1043
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001044void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001045{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001046 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001047 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001048}
1049
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001050void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1051 GLuint index,
1052 GLintptr offset,
1053 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +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.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001057}
1058
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001059void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001060{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001061 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001062 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001063}
1064
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001065void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1066 GLuint index,
1067 GLintptr offset,
1068 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001069{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001070 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001071 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001072}
1073
Jiajia Qin6eafb042016-12-27 17:04:07 +08001074void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1075{
1076 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1077 mGLState.setGenericAtomicCounterBufferBinding(buffer);
1078}
1079
1080void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1081 GLuint index,
1082 GLintptr offset,
1083 GLsizeiptr size)
1084{
1085 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1086 mGLState.setIndexedAtomicCounterBufferBinding(index, buffer, offset, size);
1087}
1088
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001089void Context::bindCopyReadBuffer(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.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001093}
1094
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001095void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +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.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001099}
1100
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001101void Context::bindPixelPackBuffer(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.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001105}
1106
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001107void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001108{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001109 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001110 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001111}
1112
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001113void Context::useProgram(GLuint program)
1114{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001115 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001116}
1117
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001118void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001119{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001120 TransformFeedback *transformFeedback =
1121 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001122 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001123}
1124
Geoff Lang5aad9672014-09-08 11:10:42 -04001125Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001126{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001127 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001128 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001129
Geoff Lang5aad9672014-09-08 11:10:42 -04001130 // begin query
1131 Error error = queryObject->begin();
1132 if (error.isError())
1133 {
1134 return error;
1135 }
1136
1137 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001138 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001139
He Yunchaoacd18982017-01-04 10:46:42 +08001140 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001141}
1142
Geoff Lang5aad9672014-09-08 11:10:42 -04001143Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001144{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001145 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001146 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001147
Geoff Lang5aad9672014-09-08 11:10:42 -04001148 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001149
Geoff Lang5aad9672014-09-08 11:10:42 -04001150 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001151 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001152
1153 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001154}
1155
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001156Error Context::queryCounter(GLuint id, GLenum target)
1157{
1158 ASSERT(target == GL_TIMESTAMP_EXT);
1159
1160 Query *queryObject = getQuery(id, true, target);
1161 ASSERT(queryObject);
1162
1163 return queryObject->queryCounter();
1164}
1165
1166void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1167{
1168 switch (pname)
1169 {
1170 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001171 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001172 break;
1173 case GL_QUERY_COUNTER_BITS_EXT:
1174 switch (target)
1175 {
1176 case GL_TIME_ELAPSED_EXT:
1177 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1178 break;
1179 case GL_TIMESTAMP_EXT:
1180 params[0] = getExtensions().queryCounterBitsTimestamp;
1181 break;
1182 default:
1183 UNREACHABLE();
1184 params[0] = 0;
1185 break;
1186 }
1187 break;
1188 default:
1189 UNREACHABLE();
1190 return;
1191 }
1192}
1193
Geoff Lang2186c382016-10-14 10:54:54 -04001194void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001195{
Geoff Lang2186c382016-10-14 10:54:54 -04001196 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001197}
1198
Geoff Lang2186c382016-10-14 10:54:54 -04001199void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001200{
Geoff Lang2186c382016-10-14 10:54:54 -04001201 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001202}
1203
Geoff Lang2186c382016-10-14 10:54:54 -04001204void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001205{
Geoff Lang2186c382016-10-14 10:54:54 -04001206 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001207}
1208
Geoff Lang2186c382016-10-14 10:54:54 -04001209void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001210{
Geoff Lang2186c382016-10-14 10:54:54 -04001211 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001212}
1213
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001214Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001215{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001216 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001217}
1218
Jamie Madill33dc8432013-07-26 11:55:05 -04001219FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001220{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001221 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001222
Jamie Madill33dc8432013-07-26 11:55:05 -04001223 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001224 {
1225 return NULL;
1226 }
1227 else
1228 {
1229 return fence->second;
1230 }
1231}
1232
1233Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1234{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001235 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236
1237 if (query == mQueryMap.end())
1238 {
1239 return NULL;
1240 }
1241 else
1242 {
1243 if (!query->second && create)
1244 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001245 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246 query->second->addRef();
1247 }
1248 return query->second;
1249 }
1250}
1251
Geoff Lang70d0f492015-12-10 17:45:46 -05001252Query *Context::getQuery(GLuint handle) const
1253{
1254 auto iter = mQueryMap.find(handle);
1255 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1256}
1257
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001258Texture *Context::getTargetTexture(GLenum target) const
1259{
Ian Ewellbda75592016-04-18 17:25:54 -04001260 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001261 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001262}
1263
Geoff Lang76b10c92014-09-05 16:28:14 -04001264Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001265{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001266 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267}
1268
Geoff Lang492a7e42014-11-05 13:27:06 -05001269Compiler *Context::getCompiler() const
1270{
1271 return mCompiler;
1272}
1273
Jamie Madill893ab082014-05-16 16:56:10 -04001274void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275{
1276 switch (pname)
1277 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001278 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001279 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001281 mGLState.getBooleanv(pname, params);
1282 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001283 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284}
1285
Jamie Madill893ab082014-05-16 16:56:10 -04001286void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001287{
Shannon Woods53a94a82014-06-24 15:20:36 -04001288 // Queries about context capabilities and maximums are answered by Context.
1289 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001290 switch (pname)
1291 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001292 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001293 params[0] = mCaps.minAliasedLineWidth;
1294 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001295 break;
1296 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001297 params[0] = mCaps.minAliasedPointSize;
1298 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001299 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001300 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001301 ASSERT(mExtensions.textureFilterAnisotropic);
1302 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001303 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001304 case GL_MAX_TEXTURE_LOD_BIAS:
1305 *params = mCaps.maxLODBias;
1306 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001307
1308 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1309 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1310 {
1311 ASSERT(mExtensions.pathRendering);
1312 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1313 memcpy(params, m, 16 * sizeof(GLfloat));
1314 }
1315 break;
1316
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001317 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001318 mGLState.getFloatv(pname, params);
1319 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001320 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001321}
1322
Jamie Madill893ab082014-05-16 16:56:10 -04001323void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324{
Shannon Woods53a94a82014-06-24 15:20:36 -04001325 // Queries about context capabilities and maximums are answered by Context.
1326 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001327
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 switch (pname)
1329 {
Geoff Lang301d1612014-07-09 10:34:37 -04001330 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1331 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1332 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001333 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1334 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1335 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001336 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1337 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1338 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001339 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001340 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1341 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1342 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001343 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001344 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001345 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1346 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1347 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1348 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001349 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1350 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001351 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1352 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001353 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001354 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1355 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1356 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1357 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001358 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001359 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001360 break;
1361 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001362 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001363 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001364 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1365 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001366 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1367 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1368 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001369 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1370 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1371 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001372 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001373 case GL_MAX_VIEWPORT_DIMS:
1374 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001375 params[0] = mCaps.maxViewportWidth;
1376 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001377 }
1378 break;
1379 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001380 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001381 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001382 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1383 *params = mResetStrategy;
1384 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001385 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001386 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001387 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001388 case GL_SHADER_BINARY_FORMATS:
1389 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1390 break;
1391 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001392 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001393 break;
1394 case GL_PROGRAM_BINARY_FORMATS:
1395 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001396 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001397 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001398 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001399 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001400
1401 // GL_KHR_debug
1402 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1403 *params = mExtensions.maxDebugMessageLength;
1404 break;
1405 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1406 *params = mExtensions.maxDebugLoggedMessages;
1407 break;
1408 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1409 *params = mExtensions.maxDebugGroupStackDepth;
1410 break;
1411 case GL_MAX_LABEL_LENGTH:
1412 *params = mExtensions.maxLabelLength;
1413 break;
1414
Ian Ewell53f59f42016-01-28 17:36:55 -05001415 // GL_EXT_disjoint_timer_query
1416 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001417 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001418 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001419 case GL_MAX_FRAMEBUFFER_WIDTH:
1420 *params = mCaps.maxFramebufferWidth;
1421 break;
1422 case GL_MAX_FRAMEBUFFER_HEIGHT:
1423 *params = mCaps.maxFramebufferHeight;
1424 break;
1425 case GL_MAX_FRAMEBUFFER_SAMPLES:
1426 *params = mCaps.maxFramebufferSamples;
1427 break;
1428 case GL_MAX_SAMPLE_MASK_WORDS:
1429 *params = mCaps.maxSampleMaskWords;
1430 break;
1431 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1432 *params = mCaps.maxColorTextureSamples;
1433 break;
1434 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1435 *params = mCaps.maxDepthTextureSamples;
1436 break;
1437 case GL_MAX_INTEGER_SAMPLES:
1438 *params = mCaps.maxIntegerSamples;
1439 break;
1440 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1441 *params = mCaps.maxVertexAttribRelativeOffset;
1442 break;
1443 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1444 *params = mCaps.maxVertexAttribBindings;
1445 break;
1446 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1447 *params = mCaps.maxVertexAttribStride;
1448 break;
1449 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1450 *params = mCaps.maxVertexAtomicCounterBuffers;
1451 break;
1452 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1453 *params = mCaps.maxVertexAtomicCounters;
1454 break;
1455 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1456 *params = mCaps.maxVertexImageUniforms;
1457 break;
1458 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1459 *params = mCaps.maxVertexShaderStorageBlocks;
1460 break;
1461 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1462 *params = mCaps.maxFragmentAtomicCounterBuffers;
1463 break;
1464 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1465 *params = mCaps.maxFragmentAtomicCounters;
1466 break;
1467 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1468 *params = mCaps.maxFragmentImageUniforms;
1469 break;
1470 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1471 *params = mCaps.maxFragmentShaderStorageBlocks;
1472 break;
1473 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1474 *params = mCaps.minProgramTextureGatherOffset;
1475 break;
1476 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1477 *params = mCaps.maxProgramTextureGatherOffset;
1478 break;
1479 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1480 *params = mCaps.maxComputeWorkGroupInvocations;
1481 break;
1482 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1483 *params = mCaps.maxComputeUniformBlocks;
1484 break;
1485 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1486 *params = mCaps.maxComputeTextureImageUnits;
1487 break;
1488 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1489 *params = mCaps.maxComputeSharedMemorySize;
1490 break;
1491 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1492 *params = mCaps.maxComputeUniformComponents;
1493 break;
1494 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1495 *params = mCaps.maxComputeAtomicCounterBuffers;
1496 break;
1497 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1498 *params = mCaps.maxComputeAtomicCounters;
1499 break;
1500 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1501 *params = mCaps.maxComputeImageUniforms;
1502 break;
1503 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1504 *params = mCaps.maxCombinedComputeUniformComponents;
1505 break;
1506 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1507 *params = mCaps.maxComputeShaderStorageBlocks;
1508 break;
1509 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1510 *params = mCaps.maxCombinedShaderOutputResources;
1511 break;
1512 case GL_MAX_UNIFORM_LOCATIONS:
1513 *params = mCaps.maxUniformLocations;
1514 break;
1515 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1516 *params = mCaps.maxAtomicCounterBufferBindings;
1517 break;
1518 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1519 *params = mCaps.maxAtomicCounterBufferSize;
1520 break;
1521 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1522 *params = mCaps.maxCombinedAtomicCounterBuffers;
1523 break;
1524 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1525 *params = mCaps.maxCombinedAtomicCounters;
1526 break;
1527 case GL_MAX_IMAGE_UNITS:
1528 *params = mCaps.maxImageUnits;
1529 break;
1530 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1531 *params = mCaps.maxCombinedImageUniforms;
1532 break;
1533 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1534 *params = mCaps.maxShaderStorageBufferBindings;
1535 break;
1536 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1537 *params = mCaps.maxCombinedShaderStorageBlocks;
1538 break;
1539 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1540 *params = mCaps.shaderStorageBufferOffsetAlignment;
1541 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001542 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001543 mGLState.getIntegerv(mState, pname, params);
1544 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001545 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001546}
1547
Jamie Madill893ab082014-05-16 16:56:10 -04001548void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001549{
Shannon Woods53a94a82014-06-24 15:20:36 -04001550 // Queries about context capabilities and maximums are answered by Context.
1551 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001552 switch (pname)
1553 {
1554 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001555 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001556 break;
1557 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001558 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001559 break;
1560 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001561 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001562 break;
1563 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001564 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001565 break;
1566 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001567 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001568 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001569
1570 // GL_EXT_disjoint_timer_query
1571 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001572 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001573 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001574
1575 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1576 *params = mCaps.maxShaderStorageBlockSize;
1577 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001578 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001579 UNREACHABLE();
1580 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001581 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001582}
1583
Geoff Lang70d0f492015-12-10 17:45:46 -05001584void Context::getPointerv(GLenum pname, void **params) const
1585{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001586 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001587}
1588
Martin Radev66fb8202016-07-28 11:45:20 +03001589void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001590{
Shannon Woods53a94a82014-06-24 15:20:36 -04001591 // Queries about context capabilities and maximums are answered by Context.
1592 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001593
1594 GLenum nativeType;
1595 unsigned int numParams;
1596 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1597 ASSERT(queryStatus);
1598
1599 if (nativeType == GL_INT)
1600 {
1601 switch (target)
1602 {
1603 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1604 ASSERT(index < 3u);
1605 *data = mCaps.maxComputeWorkGroupCount[index];
1606 break;
1607 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1608 ASSERT(index < 3u);
1609 *data = mCaps.maxComputeWorkGroupSize[index];
1610 break;
1611 default:
1612 mGLState.getIntegeri_v(target, index, data);
1613 }
1614 }
1615 else
1616 {
1617 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1618 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001619}
1620
Martin Radev66fb8202016-07-28 11:45:20 +03001621void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001622{
Shannon Woods53a94a82014-06-24 15:20:36 -04001623 // Queries about context capabilities and maximums are answered by Context.
1624 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001625
1626 GLenum nativeType;
1627 unsigned int numParams;
1628 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1629 ASSERT(queryStatus);
1630
1631 if (nativeType == GL_INT_64_ANGLEX)
1632 {
1633 mGLState.getInteger64i_v(target, index, data);
1634 }
1635 else
1636 {
1637 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1638 }
1639}
1640
1641void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1642{
1643 // Queries about context capabilities and maximums are answered by Context.
1644 // Queries about current GL state values are answered by State.
1645
1646 GLenum nativeType;
1647 unsigned int numParams;
1648 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1649 ASSERT(queryStatus);
1650
1651 if (nativeType == GL_BOOL)
1652 {
1653 mGLState.getBooleani_v(target, index, data);
1654 }
1655 else
1656 {
1657 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1658 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001659}
1660
He Yunchao010e4db2017-03-03 14:22:06 +08001661void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1662{
1663 Buffer *buffer = mGLState.getTargetBuffer(target);
1664 QueryBufferParameteriv(buffer, pname, params);
1665}
1666
1667void Context::getFramebufferAttachmentParameteriv(GLenum target,
1668 GLenum attachment,
1669 GLenum pname,
1670 GLint *params)
1671{
1672 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1673 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1674}
1675
1676void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1677{
1678 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1679 QueryRenderbufferiv(this, renderbuffer, pname, params);
1680}
1681
1682void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1683{
1684 Texture *texture = getTargetTexture(target);
1685 QueryTexParameterfv(texture, pname, params);
1686}
1687
1688void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1689{
1690 Texture *texture = getTargetTexture(target);
1691 QueryTexParameteriv(texture, pname, params);
1692}
1693void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1694{
1695 Texture *texture = getTargetTexture(target);
1696 SetTexParameterf(texture, pname, param);
1697}
1698
1699void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1700{
1701 Texture *texture = getTargetTexture(target);
1702 SetTexParameterfv(texture, pname, params);
1703}
1704
1705void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1706{
1707 Texture *texture = getTargetTexture(target);
1708 SetTexParameteri(texture, pname, param);
1709}
1710
1711void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1712{
1713 Texture *texture = getTargetTexture(target);
1714 SetTexParameteriv(texture, pname, params);
1715}
1716
Jamie Madill675fe712016-12-19 13:07:54 -05001717void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001718{
Jamie Madill1b94d432015-08-07 13:23:23 -04001719 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001720 auto error = mImplementation->drawArrays(mode, first, count);
1721 handleError(error);
1722 if (!error.isError())
1723 {
1724 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1725 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001726}
1727
Jamie Madill675fe712016-12-19 13:07:54 -05001728void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001729{
1730 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001731 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1732 handleError(error);
1733 if (!error.isError())
1734 {
1735 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1736 }
Geoff Langf6db0982015-08-25 13:04:00 -04001737}
1738
Jamie Madill675fe712016-12-19 13:07:54 -05001739void Context::drawElements(GLenum mode,
1740 GLsizei count,
1741 GLenum type,
1742 const GLvoid *indices,
1743 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001744{
Jamie Madill1b94d432015-08-07 13:23:23 -04001745 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001746 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001747}
1748
Jamie Madill675fe712016-12-19 13:07:54 -05001749void Context::drawElementsInstanced(GLenum mode,
1750 GLsizei count,
1751 GLenum type,
1752 const GLvoid *indices,
1753 GLsizei instances,
1754 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001755{
1756 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001757 handleError(
1758 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001759}
1760
Jamie Madill675fe712016-12-19 13:07:54 -05001761void Context::drawRangeElements(GLenum mode,
1762 GLuint start,
1763 GLuint end,
1764 GLsizei count,
1765 GLenum type,
1766 const GLvoid *indices,
1767 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001768{
1769 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001770 handleError(
1771 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001772}
1773
Jiajia Qind9671222016-11-29 16:30:31 +08001774void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1775{
1776 syncRendererState();
1777 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1778}
1779
1780void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1781{
1782 syncRendererState();
1783 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1784}
1785
Jamie Madill675fe712016-12-19 13:07:54 -05001786void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001787{
Jamie Madill675fe712016-12-19 13:07:54 -05001788 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001789}
1790
Jamie Madill675fe712016-12-19 13:07:54 -05001791void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001792{
Jamie Madill675fe712016-12-19 13:07:54 -05001793 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001794}
1795
Austin Kinross6ee1e782015-05-29 17:05:37 -07001796void Context::insertEventMarker(GLsizei length, const char *marker)
1797{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001798 ASSERT(mImplementation);
1799 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001800}
1801
1802void Context::pushGroupMarker(GLsizei length, const char *marker)
1803{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001804 ASSERT(mImplementation);
1805 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001806}
1807
1808void Context::popGroupMarker()
1809{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001810 ASSERT(mImplementation);
1811 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001812}
1813
Geoff Langd8605522016-04-13 10:19:12 -04001814void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1815{
1816 Program *programObject = getProgram(program);
1817 ASSERT(programObject);
1818
1819 programObject->bindUniformLocation(location, name);
1820}
1821
Sami Väisänena797e062016-05-12 15:23:40 +03001822void Context::setCoverageModulation(GLenum components)
1823{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001824 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001825}
1826
Sami Väisänene45e53b2016-05-25 10:36:04 +03001827void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1828{
1829 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1830}
1831
1832void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1833{
1834 GLfloat I[16];
1835 angle::Matrix<GLfloat>::setToIdentity(I);
1836
1837 mGLState.loadPathRenderingMatrix(matrixMode, I);
1838}
1839
1840void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1841{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001842 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001843 if (!pathObj)
1844 return;
1845
1846 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1847 syncRendererState();
1848
1849 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1850}
1851
1852void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1853{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001854 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001855 if (!pathObj)
1856 return;
1857
1858 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1859 syncRendererState();
1860
1861 mImplementation->stencilStrokePath(pathObj, reference, mask);
1862}
1863
1864void Context::coverFillPath(GLuint path, GLenum coverMode)
1865{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001866 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001867 if (!pathObj)
1868 return;
1869
1870 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1871 syncRendererState();
1872
1873 mImplementation->coverFillPath(pathObj, coverMode);
1874}
1875
1876void Context::coverStrokePath(GLuint path, GLenum coverMode)
1877{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001878 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001879 if (!pathObj)
1880 return;
1881
1882 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1883 syncRendererState();
1884
1885 mImplementation->coverStrokePath(pathObj, coverMode);
1886}
1887
1888void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1889{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001890 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001891 if (!pathObj)
1892 return;
1893
1894 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1895 syncRendererState();
1896
1897 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1898}
1899
1900void Context::stencilThenCoverStrokePath(GLuint path,
1901 GLint reference,
1902 GLuint mask,
1903 GLenum coverMode)
1904{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001905 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001906 if (!pathObj)
1907 return;
1908
1909 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1910 syncRendererState();
1911
1912 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1913}
1914
Sami Väisänend59ca052016-06-21 16:10:00 +03001915void Context::coverFillPathInstanced(GLsizei numPaths,
1916 GLenum pathNameType,
1917 const void *paths,
1918 GLuint pathBase,
1919 GLenum coverMode,
1920 GLenum transformType,
1921 const GLfloat *transformValues)
1922{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001923 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001924
1925 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1926 syncRendererState();
1927
1928 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1929}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001930
Sami Väisänend59ca052016-06-21 16:10:00 +03001931void Context::coverStrokePathInstanced(GLsizei numPaths,
1932 GLenum pathNameType,
1933 const void *paths,
1934 GLuint pathBase,
1935 GLenum coverMode,
1936 GLenum transformType,
1937 const GLfloat *transformValues)
1938{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001939 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001940
1941 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1942 syncRendererState();
1943
1944 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1945 transformValues);
1946}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001947
Sami Väisänend59ca052016-06-21 16:10:00 +03001948void Context::stencilFillPathInstanced(GLsizei numPaths,
1949 GLenum pathNameType,
1950 const void *paths,
1951 GLuint pathBase,
1952 GLenum fillMode,
1953 GLuint mask,
1954 GLenum transformType,
1955 const GLfloat *transformValues)
1956{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001957 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001958
1959 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1960 syncRendererState();
1961
1962 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1963 transformValues);
1964}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001965
Sami Väisänend59ca052016-06-21 16:10:00 +03001966void Context::stencilStrokePathInstanced(GLsizei numPaths,
1967 GLenum pathNameType,
1968 const void *paths,
1969 GLuint pathBase,
1970 GLint reference,
1971 GLuint mask,
1972 GLenum transformType,
1973 const GLfloat *transformValues)
1974{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001975 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001976
1977 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1978 syncRendererState();
1979
1980 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1981 transformValues);
1982}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001983
Sami Väisänend59ca052016-06-21 16:10:00 +03001984void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1985 GLenum pathNameType,
1986 const void *paths,
1987 GLuint pathBase,
1988 GLenum fillMode,
1989 GLuint mask,
1990 GLenum coverMode,
1991 GLenum transformType,
1992 const GLfloat *transformValues)
1993{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001994 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001995
1996 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1997 syncRendererState();
1998
1999 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2000 transformType, transformValues);
2001}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002002
Sami Väisänend59ca052016-06-21 16:10:00 +03002003void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2004 GLenum pathNameType,
2005 const void *paths,
2006 GLuint pathBase,
2007 GLint reference,
2008 GLuint mask,
2009 GLenum coverMode,
2010 GLenum transformType,
2011 const GLfloat *transformValues)
2012{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002013 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002014
2015 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2016 syncRendererState();
2017
2018 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2019 transformType, transformValues);
2020}
2021
Sami Väisänen46eaa942016-06-29 10:26:37 +03002022void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2023{
2024 auto *programObject = getProgram(program);
2025
2026 programObject->bindFragmentInputLocation(location, name);
2027}
2028
2029void Context::programPathFragmentInputGen(GLuint program,
2030 GLint location,
2031 GLenum genMode,
2032 GLint components,
2033 const GLfloat *coeffs)
2034{
2035 auto *programObject = getProgram(program);
2036
2037 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
2038}
2039
Jamie Madill437fa652016-05-03 15:13:24 -04002040void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002041{
Geoff Langda5777c2014-07-11 09:52:58 -04002042 if (error.isError())
2043 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002044 GLenum code = error.getCode();
2045 mErrors.insert(code);
2046 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2047 {
2048 markContextLost();
2049 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002050
2051 if (!error.getMessage().empty())
2052 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002053 auto *debug = &mGLState.getDebug();
2054 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2055 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002056 }
Geoff Langda5777c2014-07-11 09:52:58 -04002057 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002058}
2059
2060// Get one of the recorded errors and clear its flag, if any.
2061// [OpenGL ES 2.0.24] section 2.5 page 13.
2062GLenum Context::getError()
2063{
Geoff Langda5777c2014-07-11 09:52:58 -04002064 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002065 {
Geoff Langda5777c2014-07-11 09:52:58 -04002066 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002067 }
Geoff Langda5777c2014-07-11 09:52:58 -04002068 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002069 {
Geoff Langda5777c2014-07-11 09:52:58 -04002070 GLenum error = *mErrors.begin();
2071 mErrors.erase(mErrors.begin());
2072 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002073 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002074}
2075
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002076// NOTE: this function should not assume that this context is current!
2077void Context::markContextLost()
2078{
2079 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002080 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002081 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002082 mContextLostForced = true;
2083 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002084 mContextLost = true;
2085}
2086
2087bool Context::isContextLost()
2088{
2089 return mContextLost;
2090}
2091
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002092GLenum Context::getResetStatus()
2093{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002094 // Even if the application doesn't want to know about resets, we want to know
2095 // as it will allow us to skip all the calls.
2096 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002097 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002098 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002099 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002100 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002101 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002102
2103 // EXT_robustness, section 2.6: If the reset notification behavior is
2104 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2105 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2106 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002107 }
2108
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002109 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2110 // status should be returned at least once, and GL_NO_ERROR should be returned
2111 // once the device has finished resetting.
2112 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002113 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002114 ASSERT(mResetStatus == GL_NO_ERROR);
2115 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002116
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002117 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002118 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002119 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002120 }
2121 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002122 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002123 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002124 // If markContextLost was used to mark the context lost then
2125 // assume that is not recoverable, and continue to report the
2126 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002127 mResetStatus = mImplementation->getResetStatus();
2128 }
Jamie Madill893ab082014-05-16 16:56:10 -04002129
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002130 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002131}
2132
2133bool Context::isResetNotificationEnabled()
2134{
2135 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2136}
2137
Corentin Walleze3b10e82015-05-20 11:06:25 -04002138const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002139{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002140 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002141}
2142
2143EGLenum Context::getClientType() const
2144{
2145 return mClientType;
2146}
2147
2148EGLenum Context::getRenderBuffer() const
2149{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002150 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2151 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002152 {
2153 return EGL_NONE;
2154 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002155
2156 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2157 ASSERT(backAttachment != nullptr);
2158 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002159}
2160
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002161VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002162{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002163 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002164 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2165 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002166 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002167 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2168 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002169
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002170 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002171 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002172
2173 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002174}
2175
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002176TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002177{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002178 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002179 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2180 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002181 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002182 transformFeedback =
2183 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002184 transformFeedback->addRef();
2185 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002186 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002187
2188 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002189}
2190
2191bool Context::isVertexArrayGenerated(GLuint vertexArray)
2192{
Geoff Langf41a7152016-09-19 15:11:17 -04002193 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002194 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2195}
2196
2197bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2198{
Geoff Langf41a7152016-09-19 15:11:17 -04002199 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002200 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2201}
2202
Shannon Woods53a94a82014-06-24 15:20:36 -04002203void Context::detachTexture(GLuint texture)
2204{
2205 // Simple pass-through to State's detachTexture method, as textures do not require
2206 // allocation map management either here or in the resource manager at detach time.
2207 // Zero textures are held by the Context, and we don't attempt to request them from
2208 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002209 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002210}
2211
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002212void Context::detachBuffer(GLuint buffer)
2213{
Yuly Novikov5807a532015-12-03 13:01:22 -05002214 // Simple pass-through to State's detachBuffer method, since
2215 // only buffer attachments to container objects that are bound to the current context
2216 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002217
Yuly Novikov5807a532015-12-03 13:01:22 -05002218 // [OpenGL ES 3.2] section 5.1.2 page 45:
2219 // Attachments to unbound container objects, such as
2220 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2221 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002222 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002223}
2224
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002225void Context::detachFramebuffer(GLuint framebuffer)
2226{
Shannon Woods53a94a82014-06-24 15:20:36 -04002227 // Framebuffer detachment is handled by Context, because 0 is a valid
2228 // Framebuffer object, and a pointer to it must be passed from Context
2229 // to State at binding time.
2230
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002231 // [OpenGL ES 2.0.24] section 4.4 page 107:
2232 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2233 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2234
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002235 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002236 {
2237 bindReadFramebuffer(0);
2238 }
2239
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002240 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002241 {
2242 bindDrawFramebuffer(0);
2243 }
2244}
2245
2246void Context::detachRenderbuffer(GLuint renderbuffer)
2247{
Jamie Madilla02315b2017-02-23 14:14:47 -05002248 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002249}
2250
Jamie Madill57a89722013-07-02 11:57:03 -04002251void Context::detachVertexArray(GLuint vertexArray)
2252{
Jamie Madill77a72f62015-04-14 11:18:32 -04002253 // Vertex array detachment is handled by Context, because 0 is a valid
2254 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002255 // binding time.
2256
Jamie Madill57a89722013-07-02 11:57:03 -04002257 // [OpenGL ES 3.0.2] section 2.10 page 43:
2258 // If a vertex array object that is currently bound is deleted, the binding
2259 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002260 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002261 {
2262 bindVertexArray(0);
2263 }
2264}
2265
Geoff Langc8058452014-02-03 12:04:11 -05002266void Context::detachTransformFeedback(GLuint transformFeedback)
2267{
Corentin Walleza2257da2016-04-19 16:43:12 -04002268 // Transform feedback detachment is handled by Context, because 0 is a valid
2269 // transform feedback, and a pointer to it must be passed from Context to State at
2270 // binding time.
2271
2272 // The OpenGL specification doesn't mention what should happen when the currently bound
2273 // transform feedback object is deleted. Since it is a container object, we treat it like
2274 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002275 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002276 {
2277 bindTransformFeedback(0);
2278 }
Geoff Langc8058452014-02-03 12:04:11 -05002279}
2280
Jamie Madilldc356042013-07-19 16:36:57 -04002281void Context::detachSampler(GLuint sampler)
2282{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002283 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002284}
2285
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002286void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2287{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002288 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002289}
2290
Jamie Madille29d1672013-07-19 16:36:57 -04002291void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2292{
Geoff Langc1984ed2016-10-07 12:41:00 -04002293 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002294 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002295 SetSamplerParameteri(samplerObject, pname, param);
2296}
Jamie Madille29d1672013-07-19 16:36:57 -04002297
Geoff Langc1984ed2016-10-07 12:41:00 -04002298void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2299{
2300 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002301 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002302 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002303}
2304
2305void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2306{
Geoff Langc1984ed2016-10-07 12:41:00 -04002307 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002308 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002309 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002310}
2311
Geoff Langc1984ed2016-10-07 12:41:00 -04002312void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002313{
Geoff Langc1984ed2016-10-07 12:41:00 -04002314 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002315 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002316 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002317}
2318
Geoff Langc1984ed2016-10-07 12:41:00 -04002319void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002320{
Geoff Langc1984ed2016-10-07 12:41:00 -04002321 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002322 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002323 QuerySamplerParameteriv(samplerObject, pname, params);
2324}
Jamie Madill9675b802013-07-19 16:36:59 -04002325
Geoff Langc1984ed2016-10-07 12:41:00 -04002326void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2327{
2328 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002329 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002330 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002331}
2332
Olli Etuahof0fee072016-03-30 15:11:58 +03002333void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2334{
2335 gl::Program *programObject = getProgram(program);
2336 ASSERT(programObject != nullptr);
2337
2338 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2339 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2340}
2341
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002342void Context::initRendererString()
2343{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002344 std::ostringstream rendererString;
2345 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002346 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002347 rendererString << ")";
2348
Geoff Langcec35902014-04-16 10:52:36 -04002349 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002350}
2351
Geoff Langc339c4e2016-11-29 10:37:36 -05002352void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002353{
Geoff Langc339c4e2016-11-29 10:37:36 -05002354 const Version &clientVersion = getClientVersion();
2355
2356 std::ostringstream versionString;
2357 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2358 << ANGLE_VERSION_STRING << ")";
2359 mVersionString = MakeStaticString(versionString.str());
2360
2361 std::ostringstream shadingLanguageVersionString;
2362 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2363 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2364 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2365 << ")";
2366 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002367}
2368
Geoff Langcec35902014-04-16 10:52:36 -04002369void Context::initExtensionStrings()
2370{
Geoff Langc339c4e2016-11-29 10:37:36 -05002371 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2372 std::ostringstream combinedStringStream;
2373 std::copy(strings.begin(), strings.end(),
2374 std::ostream_iterator<const char *>(combinedStringStream, " "));
2375 return MakeStaticString(combinedStringStream.str());
2376 };
2377
2378 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002379 for (const auto &extensionString : mExtensions.getStrings())
2380 {
2381 mExtensionStrings.push_back(MakeStaticString(extensionString));
2382 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002383 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002384
Bryan Bernhart58806562017-01-05 13:09:31 -08002385 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2386
Geoff Langc339c4e2016-11-29 10:37:36 -05002387 mRequestableExtensionStrings.clear();
2388 for (const auto &extensionInfo : GetExtensionInfoMap())
2389 {
2390 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002391 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2392 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002393 {
2394 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2395 }
2396 }
2397 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002398}
2399
Geoff Langc339c4e2016-11-29 10:37:36 -05002400const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002401{
Geoff Langc339c4e2016-11-29 10:37:36 -05002402 switch (name)
2403 {
2404 case GL_VENDOR:
2405 return reinterpret_cast<const GLubyte *>("Google Inc.");
2406
2407 case GL_RENDERER:
2408 return reinterpret_cast<const GLubyte *>(mRendererString);
2409
2410 case GL_VERSION:
2411 return reinterpret_cast<const GLubyte *>(mVersionString);
2412
2413 case GL_SHADING_LANGUAGE_VERSION:
2414 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2415
2416 case GL_EXTENSIONS:
2417 return reinterpret_cast<const GLubyte *>(mExtensionString);
2418
2419 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2420 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2421
2422 default:
2423 UNREACHABLE();
2424 return nullptr;
2425 }
Geoff Langcec35902014-04-16 10:52:36 -04002426}
2427
Geoff Langc339c4e2016-11-29 10:37:36 -05002428const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002429{
Geoff Langc339c4e2016-11-29 10:37:36 -05002430 switch (name)
2431 {
2432 case GL_EXTENSIONS:
2433 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2434
2435 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2436 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2437
2438 default:
2439 UNREACHABLE();
2440 return nullptr;
2441 }
Geoff Langcec35902014-04-16 10:52:36 -04002442}
2443
2444size_t Context::getExtensionStringCount() const
2445{
2446 return mExtensionStrings.size();
2447}
2448
Geoff Langc339c4e2016-11-29 10:37:36 -05002449void Context::requestExtension(const char *name)
2450{
2451 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2452 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2453 const auto &extension = extensionInfos.at(name);
2454 ASSERT(extension.Requestable);
2455
2456 if (mExtensions.*(extension.ExtensionsMember))
2457 {
2458 // Extension already enabled
2459 return;
2460 }
2461
2462 mExtensions.*(extension.ExtensionsMember) = true;
2463 updateCaps();
2464 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002465
2466 // Re-create the compiler with the requested extensions enabled.
2467 SafeDelete(mCompiler);
2468 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002469}
2470
2471size_t Context::getRequestableExtensionStringCount() const
2472{
2473 return mRequestableExtensionStrings.size();
2474}
2475
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002476void Context::beginTransformFeedback(GLenum primitiveMode)
2477{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002478 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002479 ASSERT(transformFeedback != nullptr);
2480 ASSERT(!transformFeedback->isPaused());
2481
Jamie Madill6c1f6712017-02-14 19:08:04 -05002482 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002483}
2484
2485bool Context::hasActiveTransformFeedback(GLuint program) const
2486{
2487 for (auto pair : mTransformFeedbackMap)
2488 {
2489 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2490 {
2491 return true;
2492 }
2493 }
2494 return false;
2495}
2496
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002497void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002498{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002499 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002500
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002501 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002502
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002503 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002504
Geoff Langeb66a6e2016-10-31 13:06:12 -04002505 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002506 {
2507 // Disable ES3+ extensions
2508 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002509 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002510 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002511 }
2512
Geoff Langeb66a6e2016-10-31 13:06:12 -04002513 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002514 {
2515 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2516 //mExtensions.sRGB = false;
2517 }
2518
Jamie Madill00ed7a12016-05-19 13:13:38 -04002519 // Some extensions are always available because they are implemented in the GL layer.
2520 mExtensions.bindUniformLocation = true;
2521 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002522 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002523 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002524 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002525
2526 // Enable the no error extension if the context was created with the flag.
2527 mExtensions.noError = mSkipValidation;
2528
Corentin Wallezccab69d2017-01-27 16:57:15 -05002529 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002530 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002531
Geoff Lang70d0f492015-12-10 17:45:46 -05002532 // Explicitly enable GL_KHR_debug
2533 mExtensions.debug = true;
2534 mExtensions.maxDebugMessageLength = 1024;
2535 mExtensions.maxDebugLoggedMessages = 1024;
2536 mExtensions.maxDebugGroupStackDepth = 1024;
2537 mExtensions.maxLabelLength = 1024;
2538
Geoff Langff5b2d52016-09-07 11:32:23 -04002539 // Explicitly enable GL_ANGLE_robust_client_memory
2540 mExtensions.robustClientMemory = true;
2541
Jamie Madille08a1d32017-03-07 17:24:06 -05002542 // Determine robust resource init availability from EGL.
2543 mExtensions.robustResourceInitialization =
2544 displayExtensions.createContextRobustResourceInitialization;
2545
Geoff Lang301d1612014-07-09 10:34:37 -04002546 // Apply implementation limits
2547 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002548 mCaps.maxVertexAttribBindings =
2549 getClientVersion() < ES_3_1
2550 ? mCaps.maxVertexAttributes
2551 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2552
Geoff Lang301d1612014-07-09 10:34:37 -04002553 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2554 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2555
2556 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002557
Geoff Langc287ea62016-09-16 14:46:51 -04002558 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002559 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002560 for (const auto &extensionInfo : GetExtensionInfoMap())
2561 {
2562 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002563 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002564 {
2565 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2566 }
2567 }
2568
2569 // Generate texture caps
2570 updateCaps();
2571}
2572
2573void Context::updateCaps()
2574{
Geoff Lang900013c2014-07-07 11:32:19 -04002575 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002576 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002577
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002578 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002579 {
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002580 GLenum format = capsIt.first;
2581 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002582
Geoff Lang5d601382014-07-22 15:14:06 -04002583 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002584
Geoff Lang0d8b7242015-09-09 14:56:53 -04002585 // Update the format caps based on the client version and extensions.
2586 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2587 // ES3.
2588 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002589 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002590 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002591 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002592 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002593 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002594
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002595 // OpenGL ES does not support multisampling with non-rendererable formats
2596 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2597 if (!formatInfo.renderSupport ||
2598 (getClientVersion() < ES_3_1 &&
2599 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002600 {
Geoff Langd87878e2014-09-19 15:42:59 -04002601 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002602 }
Geoff Langd87878e2014-09-19 15:42:59 -04002603
2604 if (formatCaps.texturable && formatInfo.compressed)
2605 {
2606 mCaps.compressedTextureFormats.push_back(format);
2607 }
2608
2609 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002610 }
2611}
2612
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002613void Context::initWorkarounds()
2614{
2615 // Lose the context upon out of memory error if the application is
2616 // expecting to watch for those events.
2617 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2618}
2619
Jamie Madill1b94d432015-08-07 13:23:23 -04002620void Context::syncRendererState()
2621{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002622 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002623 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002624 mGLState.clearDirtyBits();
2625 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002626}
2627
Jamie Madillad9f24e2016-02-12 09:27:24 -05002628void Context::syncRendererState(const State::DirtyBits &bitMask,
2629 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002630{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002631 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002632 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002633 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002634
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002635 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002636}
Jamie Madillc29968b2016-01-20 11:17:23 -05002637
2638void Context::blitFramebuffer(GLint srcX0,
2639 GLint srcY0,
2640 GLint srcX1,
2641 GLint srcY1,
2642 GLint dstX0,
2643 GLint dstY0,
2644 GLint dstX1,
2645 GLint dstY1,
2646 GLbitfield mask,
2647 GLenum filter)
2648{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002649 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002650 ASSERT(drawFramebuffer);
2651
2652 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2653 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2654
Jamie Madillad9f24e2016-02-12 09:27:24 -05002655 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002656
Jamie Madill8415b5f2016-04-26 13:41:39 -04002657 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002658}
Jamie Madillc29968b2016-01-20 11:17:23 -05002659
2660void Context::clear(GLbitfield mask)
2661{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002662 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002663 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002664}
2665
2666void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2667{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002668 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002669 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2670 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002671}
2672
2673void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2674{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002675 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002676 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2677 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002678}
2679
2680void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2681{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002682 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002683 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2684 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002685}
2686
2687void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2688{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002689 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002690 ASSERT(framebufferObject);
2691
2692 // If a buffer is not present, the clear has no effect
2693 if (framebufferObject->getDepthbuffer() == nullptr &&
2694 framebufferObject->getStencilbuffer() == nullptr)
2695 {
2696 return;
2697 }
2698
Jamie Madillad9f24e2016-02-12 09:27:24 -05002699 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002700 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2701 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002702}
2703
2704void Context::readPixels(GLint x,
2705 GLint y,
2706 GLsizei width,
2707 GLsizei height,
2708 GLenum format,
2709 GLenum type,
2710 GLvoid *pixels)
2711{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002712 if (width == 0 || height == 0)
2713 {
2714 return;
2715 }
2716
Jamie Madillad9f24e2016-02-12 09:27:24 -05002717 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002718
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002719 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002720 ASSERT(framebufferObject);
2721
2722 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002723 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002724}
2725
2726void Context::copyTexImage2D(GLenum target,
2727 GLint level,
2728 GLenum internalformat,
2729 GLint x,
2730 GLint y,
2731 GLsizei width,
2732 GLsizei height,
2733 GLint border)
2734{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002735 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002736 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002737
Jamie Madillc29968b2016-01-20 11:17:23 -05002738 Rectangle sourceArea(x, y, width, height);
2739
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002740 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002741 Texture *texture =
2742 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002743 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002744}
2745
2746void Context::copyTexSubImage2D(GLenum target,
2747 GLint level,
2748 GLint xoffset,
2749 GLint yoffset,
2750 GLint x,
2751 GLint y,
2752 GLsizei width,
2753 GLsizei height)
2754{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002755 if (width == 0 || height == 0)
2756 {
2757 return;
2758 }
2759
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002760 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002761 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002762
Jamie Madillc29968b2016-01-20 11:17:23 -05002763 Offset destOffset(xoffset, yoffset, 0);
2764 Rectangle sourceArea(x, y, width, height);
2765
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002766 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002767 Texture *texture =
2768 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002769 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002770}
2771
2772void Context::copyTexSubImage3D(GLenum target,
2773 GLint level,
2774 GLint xoffset,
2775 GLint yoffset,
2776 GLint zoffset,
2777 GLint x,
2778 GLint y,
2779 GLsizei width,
2780 GLsizei height)
2781{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002782 if (width == 0 || height == 0)
2783 {
2784 return;
2785 }
2786
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002787 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002788 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002789
Jamie Madillc29968b2016-01-20 11:17:23 -05002790 Offset destOffset(xoffset, yoffset, zoffset);
2791 Rectangle sourceArea(x, y, width, height);
2792
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002793 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002794 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002795 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002796}
2797
2798void Context::framebufferTexture2D(GLenum target,
2799 GLenum attachment,
2800 GLenum textarget,
2801 GLuint texture,
2802 GLint level)
2803{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002804 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002805 ASSERT(framebuffer);
2806
2807 if (texture != 0)
2808 {
2809 Texture *textureObj = getTexture(texture);
2810
2811 ImageIndex index = ImageIndex::MakeInvalid();
2812
2813 if (textarget == GL_TEXTURE_2D)
2814 {
2815 index = ImageIndex::Make2D(level);
2816 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002817 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2818 {
2819 ASSERT(level == 0);
2820 index = ImageIndex::Make2DMultisample();
2821 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002822 else
2823 {
2824 ASSERT(IsCubeMapTextureTarget(textarget));
2825 index = ImageIndex::MakeCube(textarget, level);
2826 }
2827
Jamie Madilla02315b2017-02-23 14:14:47 -05002828 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002829 }
2830 else
2831 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002832 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002833 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002834
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002835 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002836}
2837
2838void Context::framebufferRenderbuffer(GLenum target,
2839 GLenum attachment,
2840 GLenum renderbuffertarget,
2841 GLuint renderbuffer)
2842{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002843 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002844 ASSERT(framebuffer);
2845
2846 if (renderbuffer != 0)
2847 {
2848 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002849
2850 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002851 renderbufferObject);
2852 }
2853 else
2854 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002855 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002856 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002857
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002858 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002859}
2860
2861void Context::framebufferTextureLayer(GLenum target,
2862 GLenum attachment,
2863 GLuint texture,
2864 GLint level,
2865 GLint layer)
2866{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002867 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002868 ASSERT(framebuffer);
2869
2870 if (texture != 0)
2871 {
2872 Texture *textureObject = getTexture(texture);
2873
2874 ImageIndex index = ImageIndex::MakeInvalid();
2875
2876 if (textureObject->getTarget() == GL_TEXTURE_3D)
2877 {
2878 index = ImageIndex::Make3D(level, layer);
2879 }
2880 else
2881 {
2882 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2883 index = ImageIndex::Make2DArray(level, layer);
2884 }
2885
Jamie Madilla02315b2017-02-23 14:14:47 -05002886 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002887 }
2888 else
2889 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002890 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002891 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002892
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002893 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002894}
2895
2896void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2897{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002898 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002899 ASSERT(framebuffer);
2900 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002901 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002902}
2903
2904void Context::readBuffer(GLenum mode)
2905{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002906 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002907 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002908 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002909}
2910
2911void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2912{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002913 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002914 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002915
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002916 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002917 ASSERT(framebuffer);
2918
2919 // The specification isn't clear what should be done when the framebuffer isn't complete.
2920 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002921 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002922}
2923
2924void Context::invalidateFramebuffer(GLenum target,
2925 GLsizei numAttachments,
2926 const GLenum *attachments)
2927{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002928 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002929 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002930
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002931 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002932 ASSERT(framebuffer);
2933
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002934 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002935 {
Jamie Madill437fa652016-05-03 15:13:24 -04002936 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002937 }
Jamie Madill437fa652016-05-03 15:13:24 -04002938
2939 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002940}
2941
2942void Context::invalidateSubFramebuffer(GLenum target,
2943 GLsizei numAttachments,
2944 const GLenum *attachments,
2945 GLint x,
2946 GLint y,
2947 GLsizei width,
2948 GLsizei height)
2949{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002950 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002951 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002952
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002953 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002954 ASSERT(framebuffer);
2955
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002956 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002957 {
Jamie Madill437fa652016-05-03 15:13:24 -04002958 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002959 }
Jamie Madill437fa652016-05-03 15:13:24 -04002960
2961 Rectangle area(x, y, width, height);
2962 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002963}
2964
Jamie Madill73a84962016-02-12 09:27:23 -05002965void Context::texImage2D(GLenum target,
2966 GLint level,
2967 GLint internalformat,
2968 GLsizei width,
2969 GLsizei height,
2970 GLint border,
2971 GLenum format,
2972 GLenum type,
2973 const GLvoid *pixels)
2974{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002975 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002976
2977 Extents size(width, height, 1);
2978 Texture *texture =
2979 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002980 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2981 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002982}
2983
2984void Context::texImage3D(GLenum target,
2985 GLint level,
2986 GLint internalformat,
2987 GLsizei width,
2988 GLsizei height,
2989 GLsizei depth,
2990 GLint border,
2991 GLenum format,
2992 GLenum type,
2993 const GLvoid *pixels)
2994{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002995 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002996
2997 Extents size(width, height, depth);
2998 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002999 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3000 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003001}
3002
3003void Context::texSubImage2D(GLenum target,
3004 GLint level,
3005 GLint xoffset,
3006 GLint yoffset,
3007 GLsizei width,
3008 GLsizei height,
3009 GLenum format,
3010 GLenum type,
3011 const GLvoid *pixels)
3012{
3013 // Zero sized uploads are valid but no-ops
3014 if (width == 0 || height == 0)
3015 {
3016 return;
3017 }
3018
Jamie Madillad9f24e2016-02-12 09:27:24 -05003019 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003020
3021 Box area(xoffset, yoffset, 0, width, height, 1);
3022 Texture *texture =
3023 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003024 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3025 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003026}
3027
3028void Context::texSubImage3D(GLenum target,
3029 GLint level,
3030 GLint xoffset,
3031 GLint yoffset,
3032 GLint zoffset,
3033 GLsizei width,
3034 GLsizei height,
3035 GLsizei depth,
3036 GLenum format,
3037 GLenum type,
3038 const GLvoid *pixels)
3039{
3040 // Zero sized uploads are valid but no-ops
3041 if (width == 0 || height == 0 || depth == 0)
3042 {
3043 return;
3044 }
3045
Jamie Madillad9f24e2016-02-12 09:27:24 -05003046 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003047
3048 Box area(xoffset, yoffset, zoffset, width, height, depth);
3049 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003050 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3051 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003052}
3053
3054void Context::compressedTexImage2D(GLenum target,
3055 GLint level,
3056 GLenum internalformat,
3057 GLsizei width,
3058 GLsizei height,
3059 GLint border,
3060 GLsizei imageSize,
3061 const GLvoid *data)
3062{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003063 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003064
3065 Extents size(width, height, 1);
3066 Texture *texture =
3067 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003068 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003069 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003070 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003071}
3072
3073void Context::compressedTexImage3D(GLenum target,
3074 GLint level,
3075 GLenum internalformat,
3076 GLsizei width,
3077 GLsizei height,
3078 GLsizei depth,
3079 GLint border,
3080 GLsizei imageSize,
3081 const GLvoid *data)
3082{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003083 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003084
3085 Extents size(width, height, depth);
3086 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003087 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003088 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003089 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003090}
3091
3092void Context::compressedTexSubImage2D(GLenum target,
3093 GLint level,
3094 GLint xoffset,
3095 GLint yoffset,
3096 GLsizei width,
3097 GLsizei height,
3098 GLenum format,
3099 GLsizei imageSize,
3100 const GLvoid *data)
3101{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003102 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003103
3104 Box area(xoffset, yoffset, 0, width, height, 1);
3105 Texture *texture =
3106 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003107 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003108 format, imageSize,
3109 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003110}
3111
3112void Context::compressedTexSubImage3D(GLenum target,
3113 GLint level,
3114 GLint xoffset,
3115 GLint yoffset,
3116 GLint zoffset,
3117 GLsizei width,
3118 GLsizei height,
3119 GLsizei depth,
3120 GLenum format,
3121 GLsizei imageSize,
3122 const GLvoid *data)
3123{
3124 // Zero sized uploads are valid but no-ops
3125 if (width == 0 || height == 0)
3126 {
3127 return;
3128 }
3129
Jamie Madillad9f24e2016-02-12 09:27:24 -05003130 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003131
3132 Box area(xoffset, yoffset, zoffset, width, height, depth);
3133 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003134 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003135 format, imageSize,
3136 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003137}
3138
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003139void Context::generateMipmap(GLenum target)
3140{
3141 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003142 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003143}
3144
Geoff Lang97073d12016-04-20 10:42:34 -07003145void Context::copyTextureCHROMIUM(GLuint sourceId,
3146 GLuint destId,
3147 GLint internalFormat,
3148 GLenum destType,
3149 GLboolean unpackFlipY,
3150 GLboolean unpackPremultiplyAlpha,
3151 GLboolean unpackUnmultiplyAlpha)
3152{
3153 syncStateForTexImage();
3154
3155 gl::Texture *sourceTexture = getTexture(sourceId);
3156 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003157 handleError(destTexture->copyTexture(this, internalFormat, destType, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003158 unpackPremultiplyAlpha == GL_TRUE,
3159 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3160}
3161
3162void Context::copySubTextureCHROMIUM(GLuint sourceId,
3163 GLuint destId,
3164 GLint xoffset,
3165 GLint yoffset,
3166 GLint x,
3167 GLint y,
3168 GLsizei width,
3169 GLsizei height,
3170 GLboolean unpackFlipY,
3171 GLboolean unpackPremultiplyAlpha,
3172 GLboolean unpackUnmultiplyAlpha)
3173{
3174 // Zero sized copies are valid but no-ops
3175 if (width == 0 || height == 0)
3176 {
3177 return;
3178 }
3179
3180 syncStateForTexImage();
3181
3182 gl::Texture *sourceTexture = getTexture(sourceId);
3183 gl::Texture *destTexture = getTexture(destId);
3184 Offset offset(xoffset, yoffset, 0);
3185 Rectangle area(x, y, width, height);
Jamie Madill8897afa2017-02-06 17:17:23 -05003186 handleError(destTexture->copySubTexture(this, offset, area, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003187 unpackPremultiplyAlpha == GL_TRUE,
3188 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3189}
3190
Geoff Lang47110bf2016-04-20 11:13:22 -07003191void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3192{
3193 syncStateForTexImage();
3194
3195 gl::Texture *sourceTexture = getTexture(sourceId);
3196 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003197 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003198}
3199
Geoff Lang496c02d2016-10-20 11:38:11 -07003200void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003201{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003202 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003203 ASSERT(buffer);
3204
Geoff Lang496c02d2016-10-20 11:38:11 -07003205 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003206}
3207
3208GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3209{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003210 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003211 ASSERT(buffer);
3212
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003213 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003214 if (error.isError())
3215 {
Jamie Madill437fa652016-05-03 15:13:24 -04003216 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003217 return nullptr;
3218 }
3219
3220 return buffer->getMapPointer();
3221}
3222
3223GLboolean Context::unmapBuffer(GLenum target)
3224{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003225 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003226 ASSERT(buffer);
3227
3228 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003229 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003230 if (error.isError())
3231 {
Jamie Madill437fa652016-05-03 15:13:24 -04003232 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003233 return GL_FALSE;
3234 }
3235
3236 return result;
3237}
3238
3239GLvoid *Context::mapBufferRange(GLenum target,
3240 GLintptr offset,
3241 GLsizeiptr length,
3242 GLbitfield access)
3243{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003244 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003245 ASSERT(buffer);
3246
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003247 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003248 if (error.isError())
3249 {
Jamie Madill437fa652016-05-03 15:13:24 -04003250 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003251 return nullptr;
3252 }
3253
3254 return buffer->getMapPointer();
3255}
3256
3257void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3258{
3259 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3260}
3261
Jamie Madillad9f24e2016-02-12 09:27:24 -05003262void Context::syncStateForReadPixels()
3263{
3264 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3265}
3266
3267void Context::syncStateForTexImage()
3268{
3269 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3270}
3271
3272void Context::syncStateForClear()
3273{
3274 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3275}
3276
3277void Context::syncStateForBlit()
3278{
3279 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3280}
3281
Jamie Madillc20ab272016-06-09 07:20:46 -07003282void Context::activeTexture(GLenum texture)
3283{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003284 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003285}
3286
3287void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3288{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003289 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003290}
3291
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003292void Context::blendEquation(GLenum mode)
3293{
3294 mGLState.setBlendEquation(mode, mode);
3295}
3296
Jamie Madillc20ab272016-06-09 07:20:46 -07003297void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3298{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003299 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003300}
3301
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003302void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3303{
3304 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3305}
3306
Jamie Madillc20ab272016-06-09 07:20:46 -07003307void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3308{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003309 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003310}
3311
3312void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3313{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003314 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003315}
3316
3317void Context::clearDepthf(GLclampf depth)
3318{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003319 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003320}
3321
3322void Context::clearStencil(GLint s)
3323{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003324 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003325}
3326
3327void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3328{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003329 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003330}
3331
3332void Context::cullFace(GLenum mode)
3333{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335}
3336
3337void Context::depthFunc(GLenum func)
3338{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340}
3341
3342void Context::depthMask(GLboolean flag)
3343{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345}
3346
3347void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3348{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003350}
3351
3352void Context::disable(GLenum cap)
3353{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003355}
3356
3357void Context::disableVertexAttribArray(GLuint index)
3358{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003359 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003360}
3361
3362void Context::enable(GLenum cap)
3363{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365}
3366
3367void Context::enableVertexAttribArray(GLuint index)
3368{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370}
3371
3372void Context::frontFace(GLenum mode)
3373{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003374 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003375}
3376
3377void Context::hint(GLenum target, GLenum mode)
3378{
3379 switch (target)
3380 {
3381 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003382 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003383 break;
3384
3385 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003386 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003387 break;
3388
3389 default:
3390 UNREACHABLE();
3391 return;
3392 }
3393}
3394
3395void Context::lineWidth(GLfloat width)
3396{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003397 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003398}
3399
3400void Context::pixelStorei(GLenum pname, GLint param)
3401{
3402 switch (pname)
3403 {
3404 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003405 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003406 break;
3407
3408 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003409 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003410 break;
3411
3412 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003414 break;
3415
3416 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003417 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003418 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003419 break;
3420
3421 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003422 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003423 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003424 break;
3425
3426 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003427 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003428 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003429 break;
3430
3431 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003432 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003433 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003434 break;
3435
3436 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003437 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003438 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003439 break;
3440
3441 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003442 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003443 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003444 break;
3445
3446 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003447 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003448 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003449 break;
3450
3451 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003452 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003453 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003454 break;
3455
3456 default:
3457 UNREACHABLE();
3458 return;
3459 }
3460}
3461
3462void Context::polygonOffset(GLfloat factor, GLfloat units)
3463{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003464 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003465}
3466
3467void Context::sampleCoverage(GLclampf value, GLboolean invert)
3468{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003469 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003470}
3471
3472void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3473{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003474 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003475}
3476
3477void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3478{
3479 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3480 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003481 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003482 }
3483
3484 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3485 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003486 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003487 }
3488}
3489
3490void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3491{
3492 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3493 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003494 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003495 }
3496
3497 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3498 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003499 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003500 }
3501}
3502
3503void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3504{
3505 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3506 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003507 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003508 }
3509
3510 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3511 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003512 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003513 }
3514}
3515
3516void Context::vertexAttrib1f(GLuint index, GLfloat x)
3517{
3518 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003519 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003520}
3521
3522void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3523{
3524 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
3528void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3529{
3530 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003531 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003532}
3533
3534void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3535{
3536 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003538}
3539
3540void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3541{
3542 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003543 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003544}
3545
3546void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3547{
3548 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003550}
3551
3552void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3553{
3554 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003555 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003556}
3557
3558void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3559{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003560 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003561}
3562
3563void Context::vertexAttribPointer(GLuint index,
3564 GLint size,
3565 GLenum type,
3566 GLboolean normalized,
3567 GLsizei stride,
3568 const GLvoid *ptr)
3569{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003570 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3571 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003572}
3573
3574void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3575{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003576 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003577}
3578
3579void Context::vertexAttribIPointer(GLuint index,
3580 GLint size,
3581 GLenum type,
3582 GLsizei stride,
3583 const GLvoid *pointer)
3584{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003585 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3586 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003587}
3588
3589void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3590{
3591 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003592 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003593}
3594
3595void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3596{
3597 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003598 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003599}
3600
3601void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3602{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003603 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003604}
3605
3606void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3607{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003608 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003609}
3610
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003611void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3612{
3613 const VertexAttribCurrentValueData &currentValues =
3614 getGLState().getVertexAttribCurrentValue(index);
3615 const VertexArray *vao = getGLState().getVertexArray();
3616 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3617 currentValues, pname, params);
3618}
3619
3620void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3621{
3622 const VertexAttribCurrentValueData &currentValues =
3623 getGLState().getVertexAttribCurrentValue(index);
3624 const VertexArray *vao = getGLState().getVertexArray();
3625 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3626 currentValues, pname, params);
3627}
3628
3629void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3630{
3631 const VertexAttribCurrentValueData &currentValues =
3632 getGLState().getVertexAttribCurrentValue(index);
3633 const VertexArray *vao = getGLState().getVertexArray();
3634 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3635 currentValues, pname, params);
3636}
3637
3638void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3639{
3640 const VertexAttribCurrentValueData &currentValues =
3641 getGLState().getVertexAttribCurrentValue(index);
3642 const VertexArray *vao = getGLState().getVertexArray();
3643 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3644 currentValues, pname, params);
3645}
3646
3647void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3648{
3649 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3650 QueryVertexAttribPointerv(attrib, pname, pointer);
3651}
3652
Jamie Madillc20ab272016-06-09 07:20:46 -07003653void Context::debugMessageControl(GLenum source,
3654 GLenum type,
3655 GLenum severity,
3656 GLsizei count,
3657 const GLuint *ids,
3658 GLboolean enabled)
3659{
3660 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003661 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3662 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003663}
3664
3665void Context::debugMessageInsert(GLenum source,
3666 GLenum type,
3667 GLuint id,
3668 GLenum severity,
3669 GLsizei length,
3670 const GLchar *buf)
3671{
3672 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003673 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003674}
3675
3676void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3677{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003678 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003679}
3680
3681GLuint Context::getDebugMessageLog(GLuint count,
3682 GLsizei bufSize,
3683 GLenum *sources,
3684 GLenum *types,
3685 GLuint *ids,
3686 GLenum *severities,
3687 GLsizei *lengths,
3688 GLchar *messageLog)
3689{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003690 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3691 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003692}
3693
3694void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3695{
3696 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003697 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003698}
3699
3700void Context::popDebugGroup()
3701{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003702 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003703}
3704
Jamie Madill29639852016-09-02 15:00:09 -04003705void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3706{
3707 Buffer *buffer = mGLState.getTargetBuffer(target);
3708 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003709 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003710}
3711
3712void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3713{
3714 if (data == nullptr)
3715 {
3716 return;
3717 }
3718
3719 Buffer *buffer = mGLState.getTargetBuffer(target);
3720 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003721 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003722}
3723
Jamie Madillef300b12016-10-07 15:12:09 -04003724void Context::attachShader(GLuint program, GLuint shader)
3725{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003726 auto programObject = mState.mShaderPrograms->getProgram(program);
3727 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003728 ASSERT(programObject && shaderObject);
3729 programObject->attachShader(shaderObject);
3730}
3731
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003732const Workarounds &Context::getWorkarounds() const
3733{
3734 return mWorkarounds;
3735}
3736
Jamie Madillb0817d12016-11-01 15:48:31 -04003737void Context::copyBufferSubData(GLenum readTarget,
3738 GLenum writeTarget,
3739 GLintptr readOffset,
3740 GLintptr writeOffset,
3741 GLsizeiptr size)
3742{
3743 // if size is zero, the copy is a successful no-op
3744 if (size == 0)
3745 {
3746 return;
3747 }
3748
3749 // TODO(jmadill): cache these.
3750 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3751 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3752
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003753 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003754}
3755
Jamie Madill01a80ee2016-11-07 12:06:18 -05003756void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3757{
3758 Program *programObject = getProgram(program);
3759 // TODO(jmadill): Re-use this from the validation if possible.
3760 ASSERT(programObject);
3761 programObject->bindAttributeLocation(index, name);
3762}
3763
3764void Context::bindBuffer(GLenum target, GLuint buffer)
3765{
3766 switch (target)
3767 {
3768 case GL_ARRAY_BUFFER:
3769 bindArrayBuffer(buffer);
3770 break;
3771 case GL_ELEMENT_ARRAY_BUFFER:
3772 bindElementArrayBuffer(buffer);
3773 break;
3774 case GL_COPY_READ_BUFFER:
3775 bindCopyReadBuffer(buffer);
3776 break;
3777 case GL_COPY_WRITE_BUFFER:
3778 bindCopyWriteBuffer(buffer);
3779 break;
3780 case GL_PIXEL_PACK_BUFFER:
3781 bindPixelPackBuffer(buffer);
3782 break;
3783 case GL_PIXEL_UNPACK_BUFFER:
3784 bindPixelUnpackBuffer(buffer);
3785 break;
3786 case GL_UNIFORM_BUFFER:
3787 bindGenericUniformBuffer(buffer);
3788 break;
3789 case GL_TRANSFORM_FEEDBACK_BUFFER:
3790 bindGenericTransformFeedbackBuffer(buffer);
3791 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003792 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003793 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003794 break;
3795 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003796 if (buffer != 0)
3797 {
3798 // Binding buffers to this binding point is not implemented yet.
3799 UNIMPLEMENTED();
3800 }
Geoff Lang3b573612016-10-31 14:08:10 -04003801 break;
3802 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003803 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003804 break;
3805 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003806 if (buffer != 0)
3807 {
3808 // Binding buffers to this binding point is not implemented yet.
3809 UNIMPLEMENTED();
3810 }
Geoff Lang3b573612016-10-31 14:08:10 -04003811 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003812
3813 default:
3814 UNREACHABLE();
3815 break;
3816 }
3817}
3818
Jiajia Qin6eafb042016-12-27 17:04:07 +08003819void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3820{
3821 bindBufferRange(target, index, buffer, 0, 0);
3822}
3823
3824void Context::bindBufferRange(GLenum target,
3825 GLuint index,
3826 GLuint buffer,
3827 GLintptr offset,
3828 GLsizeiptr size)
3829{
3830 switch (target)
3831 {
3832 case GL_TRANSFORM_FEEDBACK_BUFFER:
3833 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3834 bindGenericTransformFeedbackBuffer(buffer);
3835 break;
3836 case GL_UNIFORM_BUFFER:
3837 bindIndexedUniformBuffer(buffer, index, offset, size);
3838 bindGenericUniformBuffer(buffer);
3839 break;
3840 case GL_ATOMIC_COUNTER_BUFFER:
3841 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3842 bindGenericAtomicCounterBuffer(buffer);
3843 break;
3844 case GL_SHADER_STORAGE_BUFFER:
3845 if (buffer != 0)
3846 {
3847 // Binding buffers to this binding point is not implemented yet.
3848 UNIMPLEMENTED();
3849 }
3850 break;
3851 default:
3852 UNREACHABLE();
3853 break;
3854 }
3855}
3856
Jamie Madill01a80ee2016-11-07 12:06:18 -05003857void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3858{
3859 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3860 {
3861 bindReadFramebuffer(framebuffer);
3862 }
3863
3864 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3865 {
3866 bindDrawFramebuffer(framebuffer);
3867 }
3868}
3869
3870void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3871{
3872 ASSERT(target == GL_RENDERBUFFER);
3873 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003874 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003875 mGLState.setRenderbufferBinding(object);
3876}
3877
JiangYizhoubddc46b2016-12-09 09:50:51 +08003878void Context::texStorage2DMultisample(GLenum target,
3879 GLsizei samples,
3880 GLenum internalformat,
3881 GLsizei width,
3882 GLsizei height,
3883 GLboolean fixedsamplelocations)
3884{
3885 Extents size(width, height, 1);
3886 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003887 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003888 fixedsamplelocations));
3889}
3890
3891void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3892{
3893 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3894 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3895
3896 switch (pname)
3897 {
3898 case GL_SAMPLE_POSITION:
3899 handleError(framebuffer->getSamplePosition(index, val));
3900 break;
3901 default:
3902 UNREACHABLE();
3903 }
3904}
3905
Jamie Madille8fb6402017-02-14 17:56:40 -05003906void Context::renderbufferStorage(GLenum target,
3907 GLenum internalformat,
3908 GLsizei width,
3909 GLsizei height)
3910{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003911 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3912 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3913
Jamie Madille8fb6402017-02-14 17:56:40 -05003914 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003915 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003916}
3917
3918void Context::renderbufferStorageMultisample(GLenum target,
3919 GLsizei samples,
3920 GLenum internalformat,
3921 GLsizei width,
3922 GLsizei height)
3923{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003924 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3925 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05003926
3927 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003928 handleError(
3929 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003930}
3931
JiangYizhoue18e6392017-02-20 10:32:23 +08003932void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
3933{
3934 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3935 QueryFramebufferParameteriv(framebuffer, pname, params);
3936}
3937
3938void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
3939{
3940 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3941 SetFramebufferParameteri(framebuffer, pname, param);
3942}
3943
Jamie Madillc29968b2016-01-20 11:17:23 -05003944} // namespace gl