blob: f5680b8563128c792addc5ff0279590636f3c799 [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),
Jamie Madille14951e2017-03-09 18:55:16 -0500275 mWebGLContext(GetWebGLContext(attribs)),
276 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277{
Geoff Lang077f20a2016-11-01 10:08:02 -0400278 if (mRobustAccess)
279 {
280 UNIMPLEMENTED();
281 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500283 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700284 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400285
Geoff Langeb66a6e2016-10-31 13:06:12 -0400286 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Jamie Madille08a1d32017-03-07 17:24:06 -0500287 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs),
288 GetRobustResourceInit(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100289
Shannon Woods53a94a82014-06-24 15:20:36 -0400290 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400291
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000292 // [OpenGL ES 2.0.24] section 3.7 page 83:
293 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
294 // and cube map texture state vectors respectively associated with them.
295 // In order that access to these initial textures not be lost, they are treated as texture
296 // objects all of whose names are 0.
297
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400298 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500300
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400301 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500302 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400303
Geoff Langeb66a6e2016-10-31 13:06:12 -0400304 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400305 {
306 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500308 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400309
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400310 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500311 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312 }
Geoff Lang3b573612016-10-31 14:08:10 -0400313 if (getClientVersion() >= Version(3, 1))
314 {
315 Texture *zeroTexture2DMultisample =
316 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
317 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800318
319 bindGenericAtomicCounterBuffer(0);
320 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
321 {
322 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
323 }
Geoff Lang3b573612016-10-31 14:08:10 -0400324 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000325
Ian Ewellbda75592016-04-18 17:25:54 -0400326 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
327 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400328 Texture *zeroTextureExternal =
329 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400330 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
331 }
332
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700333 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500334
Jamie Madill57a89722013-07-02 11:57:03 -0400335 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000336 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800337 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000338 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400339
Jamie Madill01a80ee2016-11-07 12:06:18 -0500340 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000341
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000342 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500343 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000344 {
345 bindIndexedUniformBuffer(0, i, 0, -1);
346 }
347
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000348 bindCopyReadBuffer(0);
349 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000350 bindPixelPackBuffer(0);
351 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000352
Geoff Langeb66a6e2016-10-31 13:06:12 -0400353 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400354 {
355 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
356 // In the initial state, a default transform feedback object is bound and treated as
357 // a transform feedback object with a name of zero. That object is bound any time
358 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400359 bindTransformFeedback(0);
360 }
Geoff Langc8058452014-02-03 12:04:11 -0500361
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700362 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500363
364 // Initialize dirty bit masks
365 // TODO(jmadill): additional ES3 state
366 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
367 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
368 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
369 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500373 // No dirty objects.
374
375 // Readpixels uses the pack state and read FBO
376 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
377 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
378 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
379 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500382 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
383
384 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
385 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
386 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
387 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
388 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
389 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
390 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
391 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
392 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
393 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
394 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
395 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
396
397 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
398 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700399 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500400 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
401 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400402
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400403 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000404}
405
Jamie Madill70ee0f62017-02-06 16:04:20 -0500406void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500408 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000409
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000411 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400412 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000413 }
414
Corentin Wallez80b24112015-08-25 16:41:57 -0400415 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000416 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400417 if (query.second != nullptr)
418 {
419 query.second->release();
420 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421 }
422
Corentin Wallez80b24112015-08-25 16:41:57 -0400423 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400424 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400425 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400426 }
427
Corentin Wallez80b24112015-08-25 16:41:57 -0400428 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500429 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500430 if (transformFeedback.second != nullptr)
431 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500432 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500433 }
Geoff Langc8058452014-02-03 12:04:11 -0500434 }
435
Jamie Madilldedd7b92014-11-05 16:30:36 -0500436 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400437 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500438 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400439 }
440 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000441
Corentin Wallezccab69d2017-01-27 16:57:15 -0500442 SafeDelete(mSurfacelessFramebuffer);
443
Jamie Madill70ee0f62017-02-06 16:04:20 -0500444 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400445
Geoff Lang492a7e42014-11-05 13:27:06 -0500446 SafeDelete(mCompiler);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500447
448 mState.mBuffers->release(this);
449 mState.mShaderPrograms->release(this);
450 mState.mTextures->release(this);
451 mState.mRenderbuffers->release(this);
452 mState.mSamplers->release(this);
453 mState.mFenceSyncs->release(this);
454 mState.mPaths->release(this);
455 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000456}
457
Jamie Madill70ee0f62017-02-06 16:04:20 -0500458Context::~Context()
459{
460}
461
462void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000464 if (!mHasBeenCurrent)
465 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000466 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500467 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400468 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000469
Corentin Wallezc295e512017-01-27 17:47:50 -0500470 int width = 0;
471 int height = 0;
472 if (surface != nullptr)
473 {
474 width = surface->getWidth();
475 height = surface->getHeight();
476 }
477
478 mGLState.setViewportParams(0, 0, width, height);
479 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000480
481 mHasBeenCurrent = true;
482 }
483
Jamie Madill1b94d432015-08-07 13:23:23 -0400484 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700485 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400486
Jamie Madill70ee0f62017-02-06 16:04:20 -0500487 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500488
489 Framebuffer *newDefault = nullptr;
490 if (surface != nullptr)
491 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500492 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500493 mCurrentSurface = surface;
494 newDefault = surface->getDefaultFramebuffer();
495 }
496 else
497 {
498 if (mSurfacelessFramebuffer == nullptr)
499 {
500 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
501 }
502
503 newDefault = mSurfacelessFramebuffer;
504 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000505
Corentin Wallez37c39792015-08-20 14:19:46 -0400506 // Update default framebuffer, the binding of the previous default
507 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400508 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700509 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400510 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700511 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400512 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700513 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400514 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700515 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400516 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500517 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400518 }
Ian Ewell292f0052016-02-04 10:37:32 -0500519
520 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700521 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000522}
523
Jamie Madill70ee0f62017-02-06 16:04:20 -0500524void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400525{
Corentin Wallez37c39792015-08-20 14:19:46 -0400526 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500527 Framebuffer *currentDefault = nullptr;
528 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400529 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500530 currentDefault = mCurrentSurface->getDefaultFramebuffer();
531 }
532 else if (mSurfacelessFramebuffer != nullptr)
533 {
534 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400535 }
536
Corentin Wallezc295e512017-01-27 17:47:50 -0500537 if (mGLState.getReadFramebuffer() == currentDefault)
538 {
539 mGLState.setReadFramebufferBinding(nullptr);
540 }
541 if (mGLState.getDrawFramebuffer() == currentDefault)
542 {
543 mGLState.setDrawFramebufferBinding(nullptr);
544 }
545 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
546
547 if (mCurrentSurface)
548 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500549 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500550 mCurrentSurface = nullptr;
551 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400552}
553
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000554GLuint Context::createBuffer()
555{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500556 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000557}
558
559GLuint Context::createProgram()
560{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500561 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000562}
563
564GLuint Context::createShader(GLenum type)
565{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500566 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000567}
568
569GLuint Context::createTexture()
570{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500571 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000572}
573
574GLuint Context::createRenderbuffer()
575{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500576 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000577}
578
Geoff Lang882033e2014-09-30 11:26:07 -0400579GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400580{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500581 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400582
Cooper Partind8e62a32015-01-29 15:21:25 -0800583 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400584}
585
Sami Väisänene45e53b2016-05-25 10:36:04 +0300586GLuint Context::createPaths(GLsizei range)
587{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500588 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300589 if (resultOrError.isError())
590 {
591 handleError(resultOrError.getError());
592 return 0;
593 }
594 return resultOrError.getResult();
595}
596
Jamie Madill57a89722013-07-02 11:57:03 -0400597GLuint Context::createVertexArray()
598{
Geoff Lang36167ab2015-12-07 10:27:14 -0500599 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
600 mVertexArrayMap[vertexArray] = nullptr;
601 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400602}
603
Jamie Madilldc356042013-07-19 16:36:57 -0400604GLuint Context::createSampler()
605{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500606 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400607}
608
Geoff Langc8058452014-02-03 12:04:11 -0500609GLuint Context::createTransformFeedback()
610{
Geoff Lang36167ab2015-12-07 10:27:14 -0500611 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
612 mTransformFeedbackMap[transformFeedback] = nullptr;
613 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500614}
615
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000616// Returns an unused framebuffer name
617GLuint Context::createFramebuffer()
618{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500619 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620}
621
Jamie Madill33dc8432013-07-26 11:55:05 -0400622GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000623{
Jamie Madill33dc8432013-07-26 11:55:05 -0400624 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400626 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000627
628 return handle;
629}
630
631// Returns an unused query name
632GLuint Context::createQuery()
633{
634 GLuint handle = mQueryHandleAllocator.allocate();
635
636 mQueryMap[handle] = NULL;
637
638 return handle;
639}
640
641void Context::deleteBuffer(GLuint buffer)
642{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500643 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000644 {
645 detachBuffer(buffer);
646 }
Jamie Madill893ab082014-05-16 16:56:10 -0400647
Jamie Madill6c1f6712017-02-14 19:08:04 -0500648 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000649}
650
651void Context::deleteShader(GLuint shader)
652{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500653 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000654}
655
656void Context::deleteProgram(GLuint program)
657{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500658 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659}
660
661void Context::deleteTexture(GLuint texture)
662{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500663 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000664 {
665 detachTexture(texture);
666 }
667
Jamie Madill6c1f6712017-02-14 19:08:04 -0500668 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000669}
670
671void Context::deleteRenderbuffer(GLuint renderbuffer)
672{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500673 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000674 {
675 detachRenderbuffer(renderbuffer);
676 }
Jamie Madill893ab082014-05-16 16:56:10 -0400677
Jamie Madill6c1f6712017-02-14 19:08:04 -0500678 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000679}
680
Jamie Madillcd055f82013-07-26 11:55:15 -0400681void Context::deleteFenceSync(GLsync fenceSync)
682{
683 // The spec specifies the underlying Fence object is not deleted until all current
684 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
685 // and since our API is currently designed for being called from a single thread, we can delete
686 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500687 mState.mFenceSyncs->deleteObject(this,
688 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400689}
690
Sami Väisänene45e53b2016-05-25 10:36:04 +0300691void Context::deletePaths(GLuint first, GLsizei range)
692{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500693 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300694}
695
696bool Context::hasPathData(GLuint path) const
697{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500698 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300699 if (pathObj == nullptr)
700 return false;
701
702 return pathObj->hasPathData();
703}
704
705bool Context::hasPath(GLuint path) const
706{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500707 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300708}
709
710void Context::setPathCommands(GLuint path,
711 GLsizei numCommands,
712 const GLubyte *commands,
713 GLsizei numCoords,
714 GLenum coordType,
715 const void *coords)
716{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500717 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300718
719 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
720}
721
722void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
723{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500724 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300725
726 switch (pname)
727 {
728 case GL_PATH_STROKE_WIDTH_CHROMIUM:
729 pathObj->setStrokeWidth(value);
730 break;
731 case GL_PATH_END_CAPS_CHROMIUM:
732 pathObj->setEndCaps(static_cast<GLenum>(value));
733 break;
734 case GL_PATH_JOIN_STYLE_CHROMIUM:
735 pathObj->setJoinStyle(static_cast<GLenum>(value));
736 break;
737 case GL_PATH_MITER_LIMIT_CHROMIUM:
738 pathObj->setMiterLimit(value);
739 break;
740 case GL_PATH_STROKE_BOUND_CHROMIUM:
741 pathObj->setStrokeBound(value);
742 break;
743 default:
744 UNREACHABLE();
745 break;
746 }
747}
748
749void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
750{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500751 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300752
753 switch (pname)
754 {
755 case GL_PATH_STROKE_WIDTH_CHROMIUM:
756 *value = pathObj->getStrokeWidth();
757 break;
758 case GL_PATH_END_CAPS_CHROMIUM:
759 *value = static_cast<GLfloat>(pathObj->getEndCaps());
760 break;
761 case GL_PATH_JOIN_STYLE_CHROMIUM:
762 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
763 break;
764 case GL_PATH_MITER_LIMIT_CHROMIUM:
765 *value = pathObj->getMiterLimit();
766 break;
767 case GL_PATH_STROKE_BOUND_CHROMIUM:
768 *value = pathObj->getStrokeBound();
769 break;
770 default:
771 UNREACHABLE();
772 break;
773 }
774}
775
776void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
777{
778 mGLState.setPathStencilFunc(func, ref, mask);
779}
780
Jamie Madill57a89722013-07-02 11:57:03 -0400781void Context::deleteVertexArray(GLuint vertexArray)
782{
Geoff Lang36167ab2015-12-07 10:27:14 -0500783 auto iter = mVertexArrayMap.find(vertexArray);
784 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000785 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500786 VertexArray *vertexArrayObject = iter->second;
787 if (vertexArrayObject != nullptr)
788 {
789 detachVertexArray(vertexArray);
790 delete vertexArrayObject;
791 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000792
Geoff Lang36167ab2015-12-07 10:27:14 -0500793 mVertexArrayMap.erase(iter);
794 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400795 }
796}
797
Jamie Madilldc356042013-07-19 16:36:57 -0400798void Context::deleteSampler(GLuint sampler)
799{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500800 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400801 {
802 detachSampler(sampler);
803 }
804
Jamie Madill6c1f6712017-02-14 19:08:04 -0500805 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400806}
807
Geoff Langc8058452014-02-03 12:04:11 -0500808void Context::deleteTransformFeedback(GLuint transformFeedback)
809{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500810 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500811 if (iter != mTransformFeedbackMap.end())
812 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500813 TransformFeedback *transformFeedbackObject = iter->second;
814 if (transformFeedbackObject != nullptr)
815 {
816 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500817 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500818 }
819
Geoff Lang50b3fe82015-12-08 14:49:12 +0000820 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500821 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500822 }
823}
824
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825void Context::deleteFramebuffer(GLuint framebuffer)
826{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500827 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000828 {
829 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000830 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500831
Jamie Madill6c1f6712017-02-14 19:08:04 -0500832 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000833}
834
Jamie Madill33dc8432013-07-26 11:55:05 -0400835void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000836{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500837 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000838
Jamie Madill33dc8432013-07-26 11:55:05 -0400839 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400841 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000842 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400843 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000844 }
845}
846
847void Context::deleteQuery(GLuint query)
848{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500849 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850 if (queryObject != mQueryMap.end())
851 {
852 mQueryHandleAllocator.release(queryObject->first);
853 if (queryObject->second)
854 {
855 queryObject->second->release();
856 }
857 mQueryMap.erase(queryObject);
858 }
859}
860
Geoff Lang70d0f492015-12-10 17:45:46 -0500861Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000862{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500863 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000864}
865
Jamie Madill570f7c82014-07-03 10:38:54 -0400866Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000867{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500868 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000869}
870
Geoff Lang70d0f492015-12-10 17:45:46 -0500871Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000872{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500873 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000874}
875
Jamie Madillcd055f82013-07-26 11:55:15 -0400876FenceSync *Context::getFenceSync(GLsync handle) const
877{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500878 return mState.mFenceSyncs->getFenceSync(
879 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400880}
881
Jamie Madill57a89722013-07-02 11:57:03 -0400882VertexArray *Context::getVertexArray(GLuint handle) const
883{
884 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500885 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400886}
887
Jamie Madilldc356042013-07-19 16:36:57 -0400888Sampler *Context::getSampler(GLuint handle) const
889{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500890 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400891}
892
Geoff Langc8058452014-02-03 12:04:11 -0500893TransformFeedback *Context::getTransformFeedback(GLuint handle) const
894{
Geoff Lang36167ab2015-12-07 10:27:14 -0500895 auto iter = mTransformFeedbackMap.find(handle);
896 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500897}
898
Geoff Lang70d0f492015-12-10 17:45:46 -0500899LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
900{
901 switch (identifier)
902 {
903 case GL_BUFFER:
904 return getBuffer(name);
905 case GL_SHADER:
906 return getShader(name);
907 case GL_PROGRAM:
908 return getProgram(name);
909 case GL_VERTEX_ARRAY:
910 return getVertexArray(name);
911 case GL_QUERY:
912 return getQuery(name);
913 case GL_TRANSFORM_FEEDBACK:
914 return getTransformFeedback(name);
915 case GL_SAMPLER:
916 return getSampler(name);
917 case GL_TEXTURE:
918 return getTexture(name);
919 case GL_RENDERBUFFER:
920 return getRenderbuffer(name);
921 case GL_FRAMEBUFFER:
922 return getFramebuffer(name);
923 default:
924 UNREACHABLE();
925 return nullptr;
926 }
927}
928
929LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
930{
931 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
932}
933
Martin Radev9d901792016-07-15 15:58:58 +0300934void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
935{
936 LabeledObject *object = getLabeledObject(identifier, name);
937 ASSERT(object != nullptr);
938
939 std::string labelName = GetObjectLabelFromPointer(length, label);
940 object->setLabel(labelName);
941}
942
943void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
944{
945 LabeledObject *object = getLabeledObjectFromPtr(ptr);
946 ASSERT(object != nullptr);
947
948 std::string labelName = GetObjectLabelFromPointer(length, label);
949 object->setLabel(labelName);
950}
951
952void Context::getObjectLabel(GLenum identifier,
953 GLuint name,
954 GLsizei bufSize,
955 GLsizei *length,
956 GLchar *label) const
957{
958 LabeledObject *object = getLabeledObject(identifier, name);
959 ASSERT(object != nullptr);
960
961 const std::string &objectLabel = object->getLabel();
962 GetObjectLabelBase(objectLabel, bufSize, length, label);
963}
964
965void Context::getObjectPtrLabel(const void *ptr,
966 GLsizei bufSize,
967 GLsizei *length,
968 GLchar *label) const
969{
970 LabeledObject *object = getLabeledObjectFromPtr(ptr);
971 ASSERT(object != nullptr);
972
973 const std::string &objectLabel = object->getLabel();
974 GetObjectLabelBase(objectLabel, bufSize, length, label);
975}
976
Jamie Madilldc356042013-07-19 16:36:57 -0400977bool Context::isSampler(GLuint samplerName) const
978{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500979 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400980}
981
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500982void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000983{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500984 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700985 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000986}
987
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800988void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
989{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500990 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800991 mGLState.setDrawIndirectBufferBinding(buffer);
992}
993
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500994void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500996 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700997 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000998}
999
Jamie Madilldedd7b92014-11-05 16:30:36 -05001000void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001001{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001002 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001003
Jamie Madilldedd7b92014-11-05 16:30:36 -05001004 if (handle == 0)
1005 {
1006 texture = mZeroTextures[target].get();
1007 }
1008 else
1009 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001010 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001011 }
1012
1013 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001014 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001015}
1016
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001017void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001018{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001019 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1020 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001022}
1023
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001024void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001025{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001026 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1027 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001028 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001029}
1030
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001031void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001032{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001033 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001034 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001038{
Geoff Lang76b10c92014-09-05 16:28:14 -04001039 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001040 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001041 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001042 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001043}
1044
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001045void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001046{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001047 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001048 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001049}
1050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001051void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1052 GLuint index,
1053 GLintptr offset,
1054 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001055{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001056 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001057 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001061{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001062 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1067 GLuint index,
1068 GLintptr offset,
1069 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001070{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001071 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001072 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001073}
1074
Jiajia Qin6eafb042016-12-27 17:04:07 +08001075void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1076{
1077 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1078 mGLState.setGenericAtomicCounterBufferBinding(buffer);
1079}
1080
1081void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1082 GLuint index,
1083 GLintptr offset,
1084 GLsizeiptr size)
1085{
1086 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1087 mGLState.setIndexedAtomicCounterBufferBinding(index, buffer, offset, size);
1088}
1089
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001090void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001091{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001092 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001093 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001094}
1095
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001096void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001097{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001098 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001099 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001100}
1101
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001102void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001103{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001104 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001105 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001106}
1107
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001108void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001109{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001110 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001111 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001112}
1113
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001114void Context::useProgram(GLuint program)
1115{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001116 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001117}
1118
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001119void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001120{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001121 TransformFeedback *transformFeedback =
1122 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001123 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001124}
1125
Geoff Lang5aad9672014-09-08 11:10:42 -04001126Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001127{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001128 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001129 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001130
Geoff Lang5aad9672014-09-08 11:10:42 -04001131 // begin query
1132 Error error = queryObject->begin();
1133 if (error.isError())
1134 {
1135 return error;
1136 }
1137
1138 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001139 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001140
He Yunchaoacd18982017-01-04 10:46:42 +08001141 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001142}
1143
Geoff Lang5aad9672014-09-08 11:10:42 -04001144Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001145{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001146 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001147 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001148
Geoff Lang5aad9672014-09-08 11:10:42 -04001149 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001150
Geoff Lang5aad9672014-09-08 11:10:42 -04001151 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001152 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001153
1154 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001155}
1156
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001157Error Context::queryCounter(GLuint id, GLenum target)
1158{
1159 ASSERT(target == GL_TIMESTAMP_EXT);
1160
1161 Query *queryObject = getQuery(id, true, target);
1162 ASSERT(queryObject);
1163
1164 return queryObject->queryCounter();
1165}
1166
1167void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1168{
1169 switch (pname)
1170 {
1171 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001172 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001173 break;
1174 case GL_QUERY_COUNTER_BITS_EXT:
1175 switch (target)
1176 {
1177 case GL_TIME_ELAPSED_EXT:
1178 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1179 break;
1180 case GL_TIMESTAMP_EXT:
1181 params[0] = getExtensions().queryCounterBitsTimestamp;
1182 break;
1183 default:
1184 UNREACHABLE();
1185 params[0] = 0;
1186 break;
1187 }
1188 break;
1189 default:
1190 UNREACHABLE();
1191 return;
1192 }
1193}
1194
Geoff Lang2186c382016-10-14 10:54:54 -04001195void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001196{
Geoff Lang2186c382016-10-14 10:54:54 -04001197 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001198}
1199
Geoff Lang2186c382016-10-14 10:54:54 -04001200void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001201{
Geoff Lang2186c382016-10-14 10:54:54 -04001202 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001203}
1204
Geoff Lang2186c382016-10-14 10:54:54 -04001205void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001206{
Geoff Lang2186c382016-10-14 10:54:54 -04001207 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001208}
1209
Geoff Lang2186c382016-10-14 10:54:54 -04001210void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001211{
Geoff Lang2186c382016-10-14 10:54:54 -04001212 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001213}
1214
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001215Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001217 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218}
1219
Jamie Madill33dc8432013-07-26 11:55:05 -04001220FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001221{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001222 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223
Jamie Madill33dc8432013-07-26 11:55:05 -04001224 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225 {
1226 return NULL;
1227 }
1228 else
1229 {
1230 return fence->second;
1231 }
1232}
1233
1234Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1235{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001236 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237
1238 if (query == mQueryMap.end())
1239 {
1240 return NULL;
1241 }
1242 else
1243 {
1244 if (!query->second && create)
1245 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001246 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001247 query->second->addRef();
1248 }
1249 return query->second;
1250 }
1251}
1252
Geoff Lang70d0f492015-12-10 17:45:46 -05001253Query *Context::getQuery(GLuint handle) const
1254{
1255 auto iter = mQueryMap.find(handle);
1256 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1257}
1258
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001259Texture *Context::getTargetTexture(GLenum target) const
1260{
Ian Ewellbda75592016-04-18 17:25:54 -04001261 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001262 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001263}
1264
Geoff Lang76b10c92014-09-05 16:28:14 -04001265Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001267 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268}
1269
Geoff Lang492a7e42014-11-05 13:27:06 -05001270Compiler *Context::getCompiler() const
1271{
1272 return mCompiler;
1273}
1274
Jamie Madill893ab082014-05-16 16:56:10 -04001275void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276{
1277 switch (pname)
1278 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001279 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001280 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001282 mGLState.getBooleanv(pname, params);
1283 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001285}
1286
Jamie Madill893ab082014-05-16 16:56:10 -04001287void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001288{
Shannon Woods53a94a82014-06-24 15:20:36 -04001289 // Queries about context capabilities and maximums are answered by Context.
1290 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001291 switch (pname)
1292 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001293 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001294 params[0] = mCaps.minAliasedLineWidth;
1295 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001296 break;
1297 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001298 params[0] = mCaps.minAliasedPointSize;
1299 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001300 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001301 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001302 ASSERT(mExtensions.textureFilterAnisotropic);
1303 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001304 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001305 case GL_MAX_TEXTURE_LOD_BIAS:
1306 *params = mCaps.maxLODBias;
1307 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001308
1309 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1310 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1311 {
1312 ASSERT(mExtensions.pathRendering);
1313 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1314 memcpy(params, m, 16 * sizeof(GLfloat));
1315 }
1316 break;
1317
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001318 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001319 mGLState.getFloatv(pname, params);
1320 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001321 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322}
1323
Jamie Madill893ab082014-05-16 16:56:10 -04001324void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001325{
Shannon Woods53a94a82014-06-24 15:20:36 -04001326 // Queries about context capabilities and maximums are answered by Context.
1327 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001328
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001329 switch (pname)
1330 {
Geoff Lang301d1612014-07-09 10:34:37 -04001331 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1332 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1333 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001334 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1335 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1336 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001337 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1338 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1339 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001340 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001341 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1342 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1343 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001344 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001345 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001346 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1347 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1348 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1349 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001350 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1351 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001352 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1353 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001354 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001355 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1356 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1357 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1358 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001359 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001360 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001361 break;
1362 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001363 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001364 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001365 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1366 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001367 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1368 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1369 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001370 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1371 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1372 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001373 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001374 case GL_MAX_VIEWPORT_DIMS:
1375 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001376 params[0] = mCaps.maxViewportWidth;
1377 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001378 }
1379 break;
1380 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001381 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001382 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001383 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1384 *params = mResetStrategy;
1385 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001386 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001387 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001388 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001389 case GL_SHADER_BINARY_FORMATS:
1390 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1391 break;
1392 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001393 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001394 break;
1395 case GL_PROGRAM_BINARY_FORMATS:
1396 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001397 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001398 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001399 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001400 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001401
1402 // GL_KHR_debug
1403 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1404 *params = mExtensions.maxDebugMessageLength;
1405 break;
1406 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1407 *params = mExtensions.maxDebugLoggedMessages;
1408 break;
1409 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1410 *params = mExtensions.maxDebugGroupStackDepth;
1411 break;
1412 case GL_MAX_LABEL_LENGTH:
1413 *params = mExtensions.maxLabelLength;
1414 break;
1415
Ian Ewell53f59f42016-01-28 17:36:55 -05001416 // GL_EXT_disjoint_timer_query
1417 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001418 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001419 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001420 case GL_MAX_FRAMEBUFFER_WIDTH:
1421 *params = mCaps.maxFramebufferWidth;
1422 break;
1423 case GL_MAX_FRAMEBUFFER_HEIGHT:
1424 *params = mCaps.maxFramebufferHeight;
1425 break;
1426 case GL_MAX_FRAMEBUFFER_SAMPLES:
1427 *params = mCaps.maxFramebufferSamples;
1428 break;
1429 case GL_MAX_SAMPLE_MASK_WORDS:
1430 *params = mCaps.maxSampleMaskWords;
1431 break;
1432 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1433 *params = mCaps.maxColorTextureSamples;
1434 break;
1435 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1436 *params = mCaps.maxDepthTextureSamples;
1437 break;
1438 case GL_MAX_INTEGER_SAMPLES:
1439 *params = mCaps.maxIntegerSamples;
1440 break;
1441 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1442 *params = mCaps.maxVertexAttribRelativeOffset;
1443 break;
1444 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1445 *params = mCaps.maxVertexAttribBindings;
1446 break;
1447 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1448 *params = mCaps.maxVertexAttribStride;
1449 break;
1450 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1451 *params = mCaps.maxVertexAtomicCounterBuffers;
1452 break;
1453 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1454 *params = mCaps.maxVertexAtomicCounters;
1455 break;
1456 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1457 *params = mCaps.maxVertexImageUniforms;
1458 break;
1459 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1460 *params = mCaps.maxVertexShaderStorageBlocks;
1461 break;
1462 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1463 *params = mCaps.maxFragmentAtomicCounterBuffers;
1464 break;
1465 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1466 *params = mCaps.maxFragmentAtomicCounters;
1467 break;
1468 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1469 *params = mCaps.maxFragmentImageUniforms;
1470 break;
1471 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1472 *params = mCaps.maxFragmentShaderStorageBlocks;
1473 break;
1474 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1475 *params = mCaps.minProgramTextureGatherOffset;
1476 break;
1477 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1478 *params = mCaps.maxProgramTextureGatherOffset;
1479 break;
1480 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1481 *params = mCaps.maxComputeWorkGroupInvocations;
1482 break;
1483 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1484 *params = mCaps.maxComputeUniformBlocks;
1485 break;
1486 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1487 *params = mCaps.maxComputeTextureImageUnits;
1488 break;
1489 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1490 *params = mCaps.maxComputeSharedMemorySize;
1491 break;
1492 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1493 *params = mCaps.maxComputeUniformComponents;
1494 break;
1495 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1496 *params = mCaps.maxComputeAtomicCounterBuffers;
1497 break;
1498 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1499 *params = mCaps.maxComputeAtomicCounters;
1500 break;
1501 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1502 *params = mCaps.maxComputeImageUniforms;
1503 break;
1504 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1505 *params = mCaps.maxCombinedComputeUniformComponents;
1506 break;
1507 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1508 *params = mCaps.maxComputeShaderStorageBlocks;
1509 break;
1510 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1511 *params = mCaps.maxCombinedShaderOutputResources;
1512 break;
1513 case GL_MAX_UNIFORM_LOCATIONS:
1514 *params = mCaps.maxUniformLocations;
1515 break;
1516 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1517 *params = mCaps.maxAtomicCounterBufferBindings;
1518 break;
1519 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1520 *params = mCaps.maxAtomicCounterBufferSize;
1521 break;
1522 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1523 *params = mCaps.maxCombinedAtomicCounterBuffers;
1524 break;
1525 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1526 *params = mCaps.maxCombinedAtomicCounters;
1527 break;
1528 case GL_MAX_IMAGE_UNITS:
1529 *params = mCaps.maxImageUnits;
1530 break;
1531 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1532 *params = mCaps.maxCombinedImageUniforms;
1533 break;
1534 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1535 *params = mCaps.maxShaderStorageBufferBindings;
1536 break;
1537 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1538 *params = mCaps.maxCombinedShaderStorageBlocks;
1539 break;
1540 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1541 *params = mCaps.shaderStorageBufferOffsetAlignment;
1542 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001543 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001544 mGLState.getIntegerv(mState, pname, params);
1545 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001546 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001547}
1548
Jamie Madill893ab082014-05-16 16:56:10 -04001549void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001550{
Shannon Woods53a94a82014-06-24 15:20:36 -04001551 // Queries about context capabilities and maximums are answered by Context.
1552 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001553 switch (pname)
1554 {
1555 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001556 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001557 break;
1558 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001559 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001560 break;
1561 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001562 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001563 break;
1564 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001565 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001566 break;
1567 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001568 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001569 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001570
1571 // GL_EXT_disjoint_timer_query
1572 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001573 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001574 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001575
1576 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1577 *params = mCaps.maxShaderStorageBlockSize;
1578 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001579 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001580 UNREACHABLE();
1581 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001582 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001583}
1584
Geoff Lang70d0f492015-12-10 17:45:46 -05001585void Context::getPointerv(GLenum pname, void **params) const
1586{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001587 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001588}
1589
Martin Radev66fb8202016-07-28 11:45:20 +03001590void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001591{
Shannon Woods53a94a82014-06-24 15:20:36 -04001592 // Queries about context capabilities and maximums are answered by Context.
1593 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001594
1595 GLenum nativeType;
1596 unsigned int numParams;
1597 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1598 ASSERT(queryStatus);
1599
1600 if (nativeType == GL_INT)
1601 {
1602 switch (target)
1603 {
1604 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1605 ASSERT(index < 3u);
1606 *data = mCaps.maxComputeWorkGroupCount[index];
1607 break;
1608 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1609 ASSERT(index < 3u);
1610 *data = mCaps.maxComputeWorkGroupSize[index];
1611 break;
1612 default:
1613 mGLState.getIntegeri_v(target, index, data);
1614 }
1615 }
1616 else
1617 {
1618 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1619 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001620}
1621
Martin Radev66fb8202016-07-28 11:45:20 +03001622void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001623{
Shannon Woods53a94a82014-06-24 15:20:36 -04001624 // Queries about context capabilities and maximums are answered by Context.
1625 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001626
1627 GLenum nativeType;
1628 unsigned int numParams;
1629 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1630 ASSERT(queryStatus);
1631
1632 if (nativeType == GL_INT_64_ANGLEX)
1633 {
1634 mGLState.getInteger64i_v(target, index, data);
1635 }
1636 else
1637 {
1638 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1639 }
1640}
1641
1642void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1643{
1644 // Queries about context capabilities and maximums are answered by Context.
1645 // Queries about current GL state values are answered by State.
1646
1647 GLenum nativeType;
1648 unsigned int numParams;
1649 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1650 ASSERT(queryStatus);
1651
1652 if (nativeType == GL_BOOL)
1653 {
1654 mGLState.getBooleani_v(target, index, data);
1655 }
1656 else
1657 {
1658 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1659 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001660}
1661
He Yunchao010e4db2017-03-03 14:22:06 +08001662void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1663{
1664 Buffer *buffer = mGLState.getTargetBuffer(target);
1665 QueryBufferParameteriv(buffer, pname, params);
1666}
1667
1668void Context::getFramebufferAttachmentParameteriv(GLenum target,
1669 GLenum attachment,
1670 GLenum pname,
1671 GLint *params)
1672{
1673 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1674 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1675}
1676
1677void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1678{
1679 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1680 QueryRenderbufferiv(this, renderbuffer, pname, params);
1681}
1682
1683void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1684{
1685 Texture *texture = getTargetTexture(target);
1686 QueryTexParameterfv(texture, pname, params);
1687}
1688
1689void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1690{
1691 Texture *texture = getTargetTexture(target);
1692 QueryTexParameteriv(texture, pname, params);
1693}
1694void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1695{
1696 Texture *texture = getTargetTexture(target);
1697 SetTexParameterf(texture, pname, param);
1698}
1699
1700void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1701{
1702 Texture *texture = getTargetTexture(target);
1703 SetTexParameterfv(texture, pname, params);
1704}
1705
1706void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1707{
1708 Texture *texture = getTargetTexture(target);
1709 SetTexParameteri(texture, pname, param);
1710}
1711
1712void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1713{
1714 Texture *texture = getTargetTexture(target);
1715 SetTexParameteriv(texture, pname, params);
1716}
1717
Jamie Madill675fe712016-12-19 13:07:54 -05001718void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001719{
Jamie Madill1b94d432015-08-07 13:23:23 -04001720 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001721 auto error = mImplementation->drawArrays(mode, first, count);
1722 handleError(error);
1723 if (!error.isError())
1724 {
1725 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1726 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001727}
1728
Jamie Madill675fe712016-12-19 13:07:54 -05001729void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001730{
1731 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001732 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1733 handleError(error);
1734 if (!error.isError())
1735 {
1736 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1737 }
Geoff Langf6db0982015-08-25 13:04:00 -04001738}
1739
Jamie Madill675fe712016-12-19 13:07:54 -05001740void Context::drawElements(GLenum mode,
1741 GLsizei count,
1742 GLenum type,
1743 const GLvoid *indices,
1744 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001745{
Jamie Madill1b94d432015-08-07 13:23:23 -04001746 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001747 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001748}
1749
Jamie Madill675fe712016-12-19 13:07:54 -05001750void Context::drawElementsInstanced(GLenum mode,
1751 GLsizei count,
1752 GLenum type,
1753 const GLvoid *indices,
1754 GLsizei instances,
1755 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001756{
1757 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001758 handleError(
1759 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001760}
1761
Jamie Madill675fe712016-12-19 13:07:54 -05001762void Context::drawRangeElements(GLenum mode,
1763 GLuint start,
1764 GLuint end,
1765 GLsizei count,
1766 GLenum type,
1767 const GLvoid *indices,
1768 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001769{
1770 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001771 handleError(
1772 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001773}
1774
Jiajia Qind9671222016-11-29 16:30:31 +08001775void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1776{
1777 syncRendererState();
1778 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1779}
1780
1781void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1782{
1783 syncRendererState();
1784 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1785}
1786
Jamie Madill675fe712016-12-19 13:07:54 -05001787void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001788{
Jamie Madill675fe712016-12-19 13:07:54 -05001789 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001790}
1791
Jamie Madill675fe712016-12-19 13:07:54 -05001792void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001793{
Jamie Madill675fe712016-12-19 13:07:54 -05001794 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001795}
1796
Austin Kinross6ee1e782015-05-29 17:05:37 -07001797void Context::insertEventMarker(GLsizei length, const char *marker)
1798{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001799 ASSERT(mImplementation);
1800 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001801}
1802
1803void Context::pushGroupMarker(GLsizei length, const char *marker)
1804{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001805 ASSERT(mImplementation);
1806 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001807}
1808
1809void Context::popGroupMarker()
1810{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001811 ASSERT(mImplementation);
1812 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001813}
1814
Geoff Langd8605522016-04-13 10:19:12 -04001815void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1816{
1817 Program *programObject = getProgram(program);
1818 ASSERT(programObject);
1819
1820 programObject->bindUniformLocation(location, name);
1821}
1822
Sami Väisänena797e062016-05-12 15:23:40 +03001823void Context::setCoverageModulation(GLenum components)
1824{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001825 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001826}
1827
Sami Väisänene45e53b2016-05-25 10:36:04 +03001828void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1829{
1830 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1831}
1832
1833void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1834{
1835 GLfloat I[16];
1836 angle::Matrix<GLfloat>::setToIdentity(I);
1837
1838 mGLState.loadPathRenderingMatrix(matrixMode, I);
1839}
1840
1841void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1842{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001843 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001844 if (!pathObj)
1845 return;
1846
1847 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1848 syncRendererState();
1849
1850 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1851}
1852
1853void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1854{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001855 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001856 if (!pathObj)
1857 return;
1858
1859 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1860 syncRendererState();
1861
1862 mImplementation->stencilStrokePath(pathObj, reference, mask);
1863}
1864
1865void Context::coverFillPath(GLuint path, GLenum coverMode)
1866{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001867 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001868 if (!pathObj)
1869 return;
1870
1871 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1872 syncRendererState();
1873
1874 mImplementation->coverFillPath(pathObj, coverMode);
1875}
1876
1877void Context::coverStrokePath(GLuint path, GLenum coverMode)
1878{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001879 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001880 if (!pathObj)
1881 return;
1882
1883 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1884 syncRendererState();
1885
1886 mImplementation->coverStrokePath(pathObj, coverMode);
1887}
1888
1889void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1890{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001891 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001892 if (!pathObj)
1893 return;
1894
1895 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1896 syncRendererState();
1897
1898 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1899}
1900
1901void Context::stencilThenCoverStrokePath(GLuint path,
1902 GLint reference,
1903 GLuint mask,
1904 GLenum coverMode)
1905{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001906 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001907 if (!pathObj)
1908 return;
1909
1910 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1911 syncRendererState();
1912
1913 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1914}
1915
Sami Väisänend59ca052016-06-21 16:10:00 +03001916void Context::coverFillPathInstanced(GLsizei numPaths,
1917 GLenum pathNameType,
1918 const void *paths,
1919 GLuint pathBase,
1920 GLenum coverMode,
1921 GLenum transformType,
1922 const GLfloat *transformValues)
1923{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001924 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001925
1926 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1927 syncRendererState();
1928
1929 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1930}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001931
Sami Väisänend59ca052016-06-21 16:10:00 +03001932void Context::coverStrokePathInstanced(GLsizei numPaths,
1933 GLenum pathNameType,
1934 const void *paths,
1935 GLuint pathBase,
1936 GLenum coverMode,
1937 GLenum transformType,
1938 const GLfloat *transformValues)
1939{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001940 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001941
1942 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1943 syncRendererState();
1944
1945 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1946 transformValues);
1947}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001948
Sami Väisänend59ca052016-06-21 16:10:00 +03001949void Context::stencilFillPathInstanced(GLsizei numPaths,
1950 GLenum pathNameType,
1951 const void *paths,
1952 GLuint pathBase,
1953 GLenum fillMode,
1954 GLuint mask,
1955 GLenum transformType,
1956 const GLfloat *transformValues)
1957{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001958 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001959
1960 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1961 syncRendererState();
1962
1963 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1964 transformValues);
1965}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001966
Sami Väisänend59ca052016-06-21 16:10:00 +03001967void Context::stencilStrokePathInstanced(GLsizei numPaths,
1968 GLenum pathNameType,
1969 const void *paths,
1970 GLuint pathBase,
1971 GLint reference,
1972 GLuint mask,
1973 GLenum transformType,
1974 const GLfloat *transformValues)
1975{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001976 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001977
1978 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1979 syncRendererState();
1980
1981 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1982 transformValues);
1983}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001984
Sami Väisänend59ca052016-06-21 16:10:00 +03001985void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1986 GLenum pathNameType,
1987 const void *paths,
1988 GLuint pathBase,
1989 GLenum fillMode,
1990 GLuint mask,
1991 GLenum coverMode,
1992 GLenum transformType,
1993 const GLfloat *transformValues)
1994{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001995 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001996
1997 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1998 syncRendererState();
1999
2000 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2001 transformType, transformValues);
2002}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002003
Sami Väisänend59ca052016-06-21 16:10:00 +03002004void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2005 GLenum pathNameType,
2006 const void *paths,
2007 GLuint pathBase,
2008 GLint reference,
2009 GLuint mask,
2010 GLenum coverMode,
2011 GLenum transformType,
2012 const GLfloat *transformValues)
2013{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002014 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002015
2016 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2017 syncRendererState();
2018
2019 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2020 transformType, transformValues);
2021}
2022
Sami Väisänen46eaa942016-06-29 10:26:37 +03002023void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2024{
2025 auto *programObject = getProgram(program);
2026
2027 programObject->bindFragmentInputLocation(location, name);
2028}
2029
2030void Context::programPathFragmentInputGen(GLuint program,
2031 GLint location,
2032 GLenum genMode,
2033 GLint components,
2034 const GLfloat *coeffs)
2035{
2036 auto *programObject = getProgram(program);
2037
2038 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
2039}
2040
Jamie Madill437fa652016-05-03 15:13:24 -04002041void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002042{
Geoff Langda5777c2014-07-11 09:52:58 -04002043 if (error.isError())
2044 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002045 GLenum code = error.getCode();
2046 mErrors.insert(code);
2047 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2048 {
2049 markContextLost();
2050 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002051
2052 if (!error.getMessage().empty())
2053 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002054 auto *debug = &mGLState.getDebug();
2055 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2056 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002057 }
Geoff Langda5777c2014-07-11 09:52:58 -04002058 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002059}
2060
2061// Get one of the recorded errors and clear its flag, if any.
2062// [OpenGL ES 2.0.24] section 2.5 page 13.
2063GLenum Context::getError()
2064{
Geoff Langda5777c2014-07-11 09:52:58 -04002065 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002066 {
Geoff Langda5777c2014-07-11 09:52:58 -04002067 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002068 }
Geoff Langda5777c2014-07-11 09:52:58 -04002069 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002070 {
Geoff Langda5777c2014-07-11 09:52:58 -04002071 GLenum error = *mErrors.begin();
2072 mErrors.erase(mErrors.begin());
2073 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002074 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002075}
2076
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002077// NOTE: this function should not assume that this context is current!
2078void Context::markContextLost()
2079{
2080 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002081 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002082 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002083 mContextLostForced = true;
2084 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002085 mContextLost = true;
2086}
2087
2088bool Context::isContextLost()
2089{
2090 return mContextLost;
2091}
2092
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002093GLenum Context::getResetStatus()
2094{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002095 // Even if the application doesn't want to know about resets, we want to know
2096 // as it will allow us to skip all the calls.
2097 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002098 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002099 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002100 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002101 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002102 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002103
2104 // EXT_robustness, section 2.6: If the reset notification behavior is
2105 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2106 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2107 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002108 }
2109
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002110 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2111 // status should be returned at least once, and GL_NO_ERROR should be returned
2112 // once the device has finished resetting.
2113 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002114 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002115 ASSERT(mResetStatus == GL_NO_ERROR);
2116 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002117
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002118 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002119 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002120 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002121 }
2122 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002123 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002124 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002125 // If markContextLost was used to mark the context lost then
2126 // assume that is not recoverable, and continue to report the
2127 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002128 mResetStatus = mImplementation->getResetStatus();
2129 }
Jamie Madill893ab082014-05-16 16:56:10 -04002130
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002131 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002132}
2133
2134bool Context::isResetNotificationEnabled()
2135{
2136 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2137}
2138
Corentin Walleze3b10e82015-05-20 11:06:25 -04002139const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002140{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002141 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002142}
2143
2144EGLenum Context::getClientType() const
2145{
2146 return mClientType;
2147}
2148
2149EGLenum Context::getRenderBuffer() const
2150{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002151 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2152 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002153 {
2154 return EGL_NONE;
2155 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002156
2157 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2158 ASSERT(backAttachment != nullptr);
2159 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002160}
2161
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002162VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002163{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002164 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002165 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2166 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002167 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002168 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2169 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002170
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002171 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002172 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002173
2174 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002175}
2176
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002177TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002178{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002179 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002180 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2181 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002182 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002183 transformFeedback =
2184 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002185 transformFeedback->addRef();
2186 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002187 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002188
2189 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002190}
2191
2192bool Context::isVertexArrayGenerated(GLuint vertexArray)
2193{
Geoff Langf41a7152016-09-19 15:11:17 -04002194 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002195 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2196}
2197
2198bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2199{
Geoff Langf41a7152016-09-19 15:11:17 -04002200 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002201 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2202}
2203
Shannon Woods53a94a82014-06-24 15:20:36 -04002204void Context::detachTexture(GLuint texture)
2205{
2206 // Simple pass-through to State's detachTexture method, as textures do not require
2207 // allocation map management either here or in the resource manager at detach time.
2208 // Zero textures are held by the Context, and we don't attempt to request them from
2209 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002210 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002211}
2212
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002213void Context::detachBuffer(GLuint buffer)
2214{
Yuly Novikov5807a532015-12-03 13:01:22 -05002215 // Simple pass-through to State's detachBuffer method, since
2216 // only buffer attachments to container objects that are bound to the current context
2217 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002218
Yuly Novikov5807a532015-12-03 13:01:22 -05002219 // [OpenGL ES 3.2] section 5.1.2 page 45:
2220 // Attachments to unbound container objects, such as
2221 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2222 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002223 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002224}
2225
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002226void Context::detachFramebuffer(GLuint framebuffer)
2227{
Shannon Woods53a94a82014-06-24 15:20:36 -04002228 // Framebuffer detachment is handled by Context, because 0 is a valid
2229 // Framebuffer object, and a pointer to it must be passed from Context
2230 // to State at binding time.
2231
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002232 // [OpenGL ES 2.0.24] section 4.4 page 107:
2233 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2234 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2235
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002236 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002237 {
2238 bindReadFramebuffer(0);
2239 }
2240
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002241 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002242 {
2243 bindDrawFramebuffer(0);
2244 }
2245}
2246
2247void Context::detachRenderbuffer(GLuint renderbuffer)
2248{
Jamie Madilla02315b2017-02-23 14:14:47 -05002249 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002250}
2251
Jamie Madill57a89722013-07-02 11:57:03 -04002252void Context::detachVertexArray(GLuint vertexArray)
2253{
Jamie Madill77a72f62015-04-14 11:18:32 -04002254 // Vertex array detachment is handled by Context, because 0 is a valid
2255 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002256 // binding time.
2257
Jamie Madill57a89722013-07-02 11:57:03 -04002258 // [OpenGL ES 3.0.2] section 2.10 page 43:
2259 // If a vertex array object that is currently bound is deleted, the binding
2260 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002261 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002262 {
2263 bindVertexArray(0);
2264 }
2265}
2266
Geoff Langc8058452014-02-03 12:04:11 -05002267void Context::detachTransformFeedback(GLuint transformFeedback)
2268{
Corentin Walleza2257da2016-04-19 16:43:12 -04002269 // Transform feedback detachment is handled by Context, because 0 is a valid
2270 // transform feedback, and a pointer to it must be passed from Context to State at
2271 // binding time.
2272
2273 // The OpenGL specification doesn't mention what should happen when the currently bound
2274 // transform feedback object is deleted. Since it is a container object, we treat it like
2275 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002276 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002277 {
2278 bindTransformFeedback(0);
2279 }
Geoff Langc8058452014-02-03 12:04:11 -05002280}
2281
Jamie Madilldc356042013-07-19 16:36:57 -04002282void Context::detachSampler(GLuint sampler)
2283{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002284 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002285}
2286
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002287void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2288{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002289 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002290}
2291
Jamie Madille29d1672013-07-19 16:36:57 -04002292void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2293{
Geoff Langc1984ed2016-10-07 12:41:00 -04002294 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002295 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002296 SetSamplerParameteri(samplerObject, pname, param);
2297}
Jamie Madille29d1672013-07-19 16:36:57 -04002298
Geoff Langc1984ed2016-10-07 12:41:00 -04002299void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2300{
2301 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002302 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002303 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002304}
2305
2306void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2307{
Geoff Langc1984ed2016-10-07 12:41:00 -04002308 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002309 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002310 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002311}
2312
Geoff Langc1984ed2016-10-07 12:41:00 -04002313void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002314{
Geoff Langc1984ed2016-10-07 12:41:00 -04002315 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002316 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002317 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002318}
2319
Geoff Langc1984ed2016-10-07 12:41:00 -04002320void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002321{
Geoff Langc1984ed2016-10-07 12:41:00 -04002322 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002323 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002324 QuerySamplerParameteriv(samplerObject, pname, params);
2325}
Jamie Madill9675b802013-07-19 16:36:59 -04002326
Geoff Langc1984ed2016-10-07 12:41:00 -04002327void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2328{
2329 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002330 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002331 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002332}
2333
Olli Etuahof0fee072016-03-30 15:11:58 +03002334void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2335{
2336 gl::Program *programObject = getProgram(program);
2337 ASSERT(programObject != nullptr);
2338
2339 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2340 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2341}
2342
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002343void Context::initRendererString()
2344{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002345 std::ostringstream rendererString;
2346 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002347 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002348 rendererString << ")";
2349
Geoff Langcec35902014-04-16 10:52:36 -04002350 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002351}
2352
Geoff Langc339c4e2016-11-29 10:37:36 -05002353void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002354{
Geoff Langc339c4e2016-11-29 10:37:36 -05002355 const Version &clientVersion = getClientVersion();
2356
2357 std::ostringstream versionString;
2358 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2359 << ANGLE_VERSION_STRING << ")";
2360 mVersionString = MakeStaticString(versionString.str());
2361
2362 std::ostringstream shadingLanguageVersionString;
2363 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2364 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2365 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2366 << ")";
2367 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002368}
2369
Geoff Langcec35902014-04-16 10:52:36 -04002370void Context::initExtensionStrings()
2371{
Geoff Langc339c4e2016-11-29 10:37:36 -05002372 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2373 std::ostringstream combinedStringStream;
2374 std::copy(strings.begin(), strings.end(),
2375 std::ostream_iterator<const char *>(combinedStringStream, " "));
2376 return MakeStaticString(combinedStringStream.str());
2377 };
2378
2379 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002380 for (const auto &extensionString : mExtensions.getStrings())
2381 {
2382 mExtensionStrings.push_back(MakeStaticString(extensionString));
2383 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002384 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002385
Bryan Bernhart58806562017-01-05 13:09:31 -08002386 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2387
Geoff Langc339c4e2016-11-29 10:37:36 -05002388 mRequestableExtensionStrings.clear();
2389 for (const auto &extensionInfo : GetExtensionInfoMap())
2390 {
2391 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002392 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2393 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002394 {
2395 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2396 }
2397 }
2398 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002399}
2400
Geoff Langc339c4e2016-11-29 10:37:36 -05002401const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002402{
Geoff Langc339c4e2016-11-29 10:37:36 -05002403 switch (name)
2404 {
2405 case GL_VENDOR:
2406 return reinterpret_cast<const GLubyte *>("Google Inc.");
2407
2408 case GL_RENDERER:
2409 return reinterpret_cast<const GLubyte *>(mRendererString);
2410
2411 case GL_VERSION:
2412 return reinterpret_cast<const GLubyte *>(mVersionString);
2413
2414 case GL_SHADING_LANGUAGE_VERSION:
2415 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2416
2417 case GL_EXTENSIONS:
2418 return reinterpret_cast<const GLubyte *>(mExtensionString);
2419
2420 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2421 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2422
2423 default:
2424 UNREACHABLE();
2425 return nullptr;
2426 }
Geoff Langcec35902014-04-16 10:52:36 -04002427}
2428
Geoff Langc339c4e2016-11-29 10:37:36 -05002429const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002430{
Geoff Langc339c4e2016-11-29 10:37:36 -05002431 switch (name)
2432 {
2433 case GL_EXTENSIONS:
2434 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2435
2436 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2437 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2438
2439 default:
2440 UNREACHABLE();
2441 return nullptr;
2442 }
Geoff Langcec35902014-04-16 10:52:36 -04002443}
2444
2445size_t Context::getExtensionStringCount() const
2446{
2447 return mExtensionStrings.size();
2448}
2449
Geoff Langc339c4e2016-11-29 10:37:36 -05002450void Context::requestExtension(const char *name)
2451{
2452 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2453 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2454 const auto &extension = extensionInfos.at(name);
2455 ASSERT(extension.Requestable);
2456
2457 if (mExtensions.*(extension.ExtensionsMember))
2458 {
2459 // Extension already enabled
2460 return;
2461 }
2462
2463 mExtensions.*(extension.ExtensionsMember) = true;
2464 updateCaps();
2465 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002466
2467 // Re-create the compiler with the requested extensions enabled.
2468 SafeDelete(mCompiler);
2469 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002470}
2471
2472size_t Context::getRequestableExtensionStringCount() const
2473{
2474 return mRequestableExtensionStrings.size();
2475}
2476
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002477void Context::beginTransformFeedback(GLenum primitiveMode)
2478{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002479 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002480 ASSERT(transformFeedback != nullptr);
2481 ASSERT(!transformFeedback->isPaused());
2482
Jamie Madill6c1f6712017-02-14 19:08:04 -05002483 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002484}
2485
2486bool Context::hasActiveTransformFeedback(GLuint program) const
2487{
2488 for (auto pair : mTransformFeedbackMap)
2489 {
2490 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2491 {
2492 return true;
2493 }
2494 }
2495 return false;
2496}
2497
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002498void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002499{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002500 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002501
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002502 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002503
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002504 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002505
Geoff Langeb66a6e2016-10-31 13:06:12 -04002506 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002507 {
2508 // Disable ES3+ extensions
2509 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002510 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002511 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002512 }
2513
Geoff Langeb66a6e2016-10-31 13:06:12 -04002514 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002515 {
2516 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2517 //mExtensions.sRGB = false;
2518 }
2519
Jamie Madill00ed7a12016-05-19 13:13:38 -04002520 // Some extensions are always available because they are implemented in the GL layer.
2521 mExtensions.bindUniformLocation = true;
2522 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002523 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002524 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002525 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002526
2527 // Enable the no error extension if the context was created with the flag.
2528 mExtensions.noError = mSkipValidation;
2529
Corentin Wallezccab69d2017-01-27 16:57:15 -05002530 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002531 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002532
Geoff Lang70d0f492015-12-10 17:45:46 -05002533 // Explicitly enable GL_KHR_debug
2534 mExtensions.debug = true;
2535 mExtensions.maxDebugMessageLength = 1024;
2536 mExtensions.maxDebugLoggedMessages = 1024;
2537 mExtensions.maxDebugGroupStackDepth = 1024;
2538 mExtensions.maxLabelLength = 1024;
2539
Geoff Langff5b2d52016-09-07 11:32:23 -04002540 // Explicitly enable GL_ANGLE_robust_client_memory
2541 mExtensions.robustClientMemory = true;
2542
Jamie Madille08a1d32017-03-07 17:24:06 -05002543 // Determine robust resource init availability from EGL.
2544 mExtensions.robustResourceInitialization =
2545 displayExtensions.createContextRobustResourceInitialization;
2546
Geoff Lang301d1612014-07-09 10:34:37 -04002547 // Apply implementation limits
2548 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002549 mCaps.maxVertexAttribBindings =
2550 getClientVersion() < ES_3_1
2551 ? mCaps.maxVertexAttributes
2552 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2553
Geoff Lang301d1612014-07-09 10:34:37 -04002554 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2555 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2556
2557 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002558
Geoff Langc287ea62016-09-16 14:46:51 -04002559 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002560 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002561 for (const auto &extensionInfo : GetExtensionInfoMap())
2562 {
2563 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002564 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002565 {
2566 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2567 }
2568 }
2569
2570 // Generate texture caps
2571 updateCaps();
2572}
2573
2574void Context::updateCaps()
2575{
Geoff Lang900013c2014-07-07 11:32:19 -04002576 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002577 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002578
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002579 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002580 {
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002581 GLenum format = capsIt.first;
2582 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002583
Geoff Lang5d601382014-07-22 15:14:06 -04002584 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002585
Geoff Lang0d8b7242015-09-09 14:56:53 -04002586 // Update the format caps based on the client version and extensions.
2587 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2588 // ES3.
2589 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002590 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002591 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002592 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002593 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002594 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002595
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002596 // OpenGL ES does not support multisampling with non-rendererable formats
2597 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2598 if (!formatInfo.renderSupport ||
2599 (getClientVersion() < ES_3_1 &&
2600 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002601 {
Geoff Langd87878e2014-09-19 15:42:59 -04002602 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002603 }
Geoff Langd87878e2014-09-19 15:42:59 -04002604
2605 if (formatCaps.texturable && formatInfo.compressed)
2606 {
2607 mCaps.compressedTextureFormats.push_back(format);
2608 }
2609
2610 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002611 }
2612}
2613
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002614void Context::initWorkarounds()
2615{
2616 // Lose the context upon out of memory error if the application is
2617 // expecting to watch for those events.
2618 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2619}
2620
Jamie Madill1b94d432015-08-07 13:23:23 -04002621void Context::syncRendererState()
2622{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002623 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002624 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002625 mGLState.clearDirtyBits();
2626 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002627}
2628
Jamie Madillad9f24e2016-02-12 09:27:24 -05002629void Context::syncRendererState(const State::DirtyBits &bitMask,
2630 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002631{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002632 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002633 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002634 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002635
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002636 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002637}
Jamie Madillc29968b2016-01-20 11:17:23 -05002638
2639void Context::blitFramebuffer(GLint srcX0,
2640 GLint srcY0,
2641 GLint srcX1,
2642 GLint srcY1,
2643 GLint dstX0,
2644 GLint dstY0,
2645 GLint dstX1,
2646 GLint dstY1,
2647 GLbitfield mask,
2648 GLenum filter)
2649{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002650 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002651 ASSERT(drawFramebuffer);
2652
2653 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2654 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2655
Jamie Madillad9f24e2016-02-12 09:27:24 -05002656 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002657
Jamie Madill8415b5f2016-04-26 13:41:39 -04002658 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002659}
Jamie Madillc29968b2016-01-20 11:17:23 -05002660
2661void Context::clear(GLbitfield mask)
2662{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002663 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002664 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002665}
2666
2667void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2668{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002669 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002670 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2671 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002672}
2673
2674void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2675{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002676 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002677 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2678 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002679}
2680
2681void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2682{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002683 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002684 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2685 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002686}
2687
2688void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2689{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002690 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002691 ASSERT(framebufferObject);
2692
2693 // If a buffer is not present, the clear has no effect
2694 if (framebufferObject->getDepthbuffer() == nullptr &&
2695 framebufferObject->getStencilbuffer() == nullptr)
2696 {
2697 return;
2698 }
2699
Jamie Madillad9f24e2016-02-12 09:27:24 -05002700 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002701 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2702 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002703}
2704
2705void Context::readPixels(GLint x,
2706 GLint y,
2707 GLsizei width,
2708 GLsizei height,
2709 GLenum format,
2710 GLenum type,
2711 GLvoid *pixels)
2712{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002713 if (width == 0 || height == 0)
2714 {
2715 return;
2716 }
2717
Jamie Madillad9f24e2016-02-12 09:27:24 -05002718 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002719
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002720 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002721 ASSERT(framebufferObject);
2722
2723 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002724 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002725}
2726
2727void Context::copyTexImage2D(GLenum target,
2728 GLint level,
2729 GLenum internalformat,
2730 GLint x,
2731 GLint y,
2732 GLsizei width,
2733 GLsizei height,
2734 GLint border)
2735{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002736 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002737 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002738
Jamie Madillc29968b2016-01-20 11:17:23 -05002739 Rectangle sourceArea(x, y, width, height);
2740
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002741 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002742 Texture *texture =
2743 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002744 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002745}
2746
2747void Context::copyTexSubImage2D(GLenum target,
2748 GLint level,
2749 GLint xoffset,
2750 GLint yoffset,
2751 GLint x,
2752 GLint y,
2753 GLsizei width,
2754 GLsizei height)
2755{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002756 if (width == 0 || height == 0)
2757 {
2758 return;
2759 }
2760
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002761 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002762 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002763
Jamie Madillc29968b2016-01-20 11:17:23 -05002764 Offset destOffset(xoffset, yoffset, 0);
2765 Rectangle sourceArea(x, y, width, height);
2766
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002767 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002768 Texture *texture =
2769 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002770 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002771}
2772
2773void Context::copyTexSubImage3D(GLenum target,
2774 GLint level,
2775 GLint xoffset,
2776 GLint yoffset,
2777 GLint zoffset,
2778 GLint x,
2779 GLint y,
2780 GLsizei width,
2781 GLsizei height)
2782{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002783 if (width == 0 || height == 0)
2784 {
2785 return;
2786 }
2787
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002788 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002789 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002790
Jamie Madillc29968b2016-01-20 11:17:23 -05002791 Offset destOffset(xoffset, yoffset, zoffset);
2792 Rectangle sourceArea(x, y, width, height);
2793
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002794 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002795 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002796 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002797}
2798
2799void Context::framebufferTexture2D(GLenum target,
2800 GLenum attachment,
2801 GLenum textarget,
2802 GLuint texture,
2803 GLint level)
2804{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002805 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002806 ASSERT(framebuffer);
2807
2808 if (texture != 0)
2809 {
2810 Texture *textureObj = getTexture(texture);
2811
2812 ImageIndex index = ImageIndex::MakeInvalid();
2813
2814 if (textarget == GL_TEXTURE_2D)
2815 {
2816 index = ImageIndex::Make2D(level);
2817 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002818 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2819 {
2820 ASSERT(level == 0);
2821 index = ImageIndex::Make2DMultisample();
2822 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002823 else
2824 {
2825 ASSERT(IsCubeMapTextureTarget(textarget));
2826 index = ImageIndex::MakeCube(textarget, level);
2827 }
2828
Jamie Madilla02315b2017-02-23 14:14:47 -05002829 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002830 }
2831 else
2832 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002833 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002834 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002835
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002836 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002837}
2838
2839void Context::framebufferRenderbuffer(GLenum target,
2840 GLenum attachment,
2841 GLenum renderbuffertarget,
2842 GLuint renderbuffer)
2843{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002844 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002845 ASSERT(framebuffer);
2846
2847 if (renderbuffer != 0)
2848 {
2849 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002850
2851 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002852 renderbufferObject);
2853 }
2854 else
2855 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002856 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002857 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002858
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002859 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002860}
2861
2862void Context::framebufferTextureLayer(GLenum target,
2863 GLenum attachment,
2864 GLuint texture,
2865 GLint level,
2866 GLint layer)
2867{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002868 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002869 ASSERT(framebuffer);
2870
2871 if (texture != 0)
2872 {
2873 Texture *textureObject = getTexture(texture);
2874
2875 ImageIndex index = ImageIndex::MakeInvalid();
2876
2877 if (textureObject->getTarget() == GL_TEXTURE_3D)
2878 {
2879 index = ImageIndex::Make3D(level, layer);
2880 }
2881 else
2882 {
2883 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2884 index = ImageIndex::Make2DArray(level, layer);
2885 }
2886
Jamie Madilla02315b2017-02-23 14:14:47 -05002887 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002888 }
2889 else
2890 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002891 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002892 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002893
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002894 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002895}
2896
2897void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2898{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002899 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002900 ASSERT(framebuffer);
2901 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002902 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002903}
2904
2905void Context::readBuffer(GLenum mode)
2906{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002907 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002908 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002909 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002910}
2911
2912void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2913{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002914 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002915 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002916
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002917 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002918 ASSERT(framebuffer);
2919
2920 // The specification isn't clear what should be done when the framebuffer isn't complete.
2921 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002922 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002923}
2924
2925void Context::invalidateFramebuffer(GLenum target,
2926 GLsizei numAttachments,
2927 const GLenum *attachments)
2928{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002929 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002930 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002931
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002932 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002933 ASSERT(framebuffer);
2934
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002935 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002936 {
Jamie Madill437fa652016-05-03 15:13:24 -04002937 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002938 }
Jamie Madill437fa652016-05-03 15:13:24 -04002939
2940 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002941}
2942
2943void Context::invalidateSubFramebuffer(GLenum target,
2944 GLsizei numAttachments,
2945 const GLenum *attachments,
2946 GLint x,
2947 GLint y,
2948 GLsizei width,
2949 GLsizei height)
2950{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002951 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002952 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002953
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002954 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002955 ASSERT(framebuffer);
2956
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002957 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002958 {
Jamie Madill437fa652016-05-03 15:13:24 -04002959 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002960 }
Jamie Madill437fa652016-05-03 15:13:24 -04002961
2962 Rectangle area(x, y, width, height);
2963 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002964}
2965
Jamie Madill73a84962016-02-12 09:27:23 -05002966void Context::texImage2D(GLenum target,
2967 GLint level,
2968 GLint internalformat,
2969 GLsizei width,
2970 GLsizei height,
2971 GLint border,
2972 GLenum format,
2973 GLenum type,
2974 const GLvoid *pixels)
2975{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002976 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002977
2978 Extents size(width, height, 1);
2979 Texture *texture =
2980 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002981 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2982 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002983}
2984
2985void Context::texImage3D(GLenum target,
2986 GLint level,
2987 GLint internalformat,
2988 GLsizei width,
2989 GLsizei height,
2990 GLsizei depth,
2991 GLint border,
2992 GLenum format,
2993 GLenum type,
2994 const GLvoid *pixels)
2995{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002996 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002997
2998 Extents size(width, height, depth);
2999 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003000 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3001 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003002}
3003
3004void Context::texSubImage2D(GLenum target,
3005 GLint level,
3006 GLint xoffset,
3007 GLint yoffset,
3008 GLsizei width,
3009 GLsizei height,
3010 GLenum format,
3011 GLenum type,
3012 const GLvoid *pixels)
3013{
3014 // Zero sized uploads are valid but no-ops
3015 if (width == 0 || height == 0)
3016 {
3017 return;
3018 }
3019
Jamie Madillad9f24e2016-02-12 09:27:24 -05003020 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003021
3022 Box area(xoffset, yoffset, 0, width, height, 1);
3023 Texture *texture =
3024 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003025 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3026 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003027}
3028
3029void Context::texSubImage3D(GLenum target,
3030 GLint level,
3031 GLint xoffset,
3032 GLint yoffset,
3033 GLint zoffset,
3034 GLsizei width,
3035 GLsizei height,
3036 GLsizei depth,
3037 GLenum format,
3038 GLenum type,
3039 const GLvoid *pixels)
3040{
3041 // Zero sized uploads are valid but no-ops
3042 if (width == 0 || height == 0 || depth == 0)
3043 {
3044 return;
3045 }
3046
Jamie Madillad9f24e2016-02-12 09:27:24 -05003047 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003048
3049 Box area(xoffset, yoffset, zoffset, width, height, depth);
3050 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003051 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3052 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003053}
3054
3055void Context::compressedTexImage2D(GLenum target,
3056 GLint level,
3057 GLenum internalformat,
3058 GLsizei width,
3059 GLsizei height,
3060 GLint border,
3061 GLsizei imageSize,
3062 const GLvoid *data)
3063{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003064 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003065
3066 Extents size(width, height, 1);
3067 Texture *texture =
3068 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003069 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003070 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003071 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003072}
3073
3074void Context::compressedTexImage3D(GLenum target,
3075 GLint level,
3076 GLenum internalformat,
3077 GLsizei width,
3078 GLsizei height,
3079 GLsizei depth,
3080 GLint border,
3081 GLsizei imageSize,
3082 const GLvoid *data)
3083{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003084 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003085
3086 Extents size(width, height, depth);
3087 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003088 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003089 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003090 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003091}
3092
3093void Context::compressedTexSubImage2D(GLenum target,
3094 GLint level,
3095 GLint xoffset,
3096 GLint yoffset,
3097 GLsizei width,
3098 GLsizei height,
3099 GLenum format,
3100 GLsizei imageSize,
3101 const GLvoid *data)
3102{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003103 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003104
3105 Box area(xoffset, yoffset, 0, width, height, 1);
3106 Texture *texture =
3107 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003108 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003109 format, imageSize,
3110 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003111}
3112
3113void Context::compressedTexSubImage3D(GLenum target,
3114 GLint level,
3115 GLint xoffset,
3116 GLint yoffset,
3117 GLint zoffset,
3118 GLsizei width,
3119 GLsizei height,
3120 GLsizei depth,
3121 GLenum format,
3122 GLsizei imageSize,
3123 const GLvoid *data)
3124{
3125 // Zero sized uploads are valid but no-ops
3126 if (width == 0 || height == 0)
3127 {
3128 return;
3129 }
3130
Jamie Madillad9f24e2016-02-12 09:27:24 -05003131 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003132
3133 Box area(xoffset, yoffset, zoffset, width, height, depth);
3134 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003135 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003136 format, imageSize,
3137 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003138}
3139
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003140void Context::generateMipmap(GLenum target)
3141{
3142 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003143 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003144}
3145
Geoff Lang97073d12016-04-20 10:42:34 -07003146void Context::copyTextureCHROMIUM(GLuint sourceId,
3147 GLuint destId,
3148 GLint internalFormat,
3149 GLenum destType,
3150 GLboolean unpackFlipY,
3151 GLboolean unpackPremultiplyAlpha,
3152 GLboolean unpackUnmultiplyAlpha)
3153{
3154 syncStateForTexImage();
3155
3156 gl::Texture *sourceTexture = getTexture(sourceId);
3157 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003158 handleError(destTexture->copyTexture(this, internalFormat, destType, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003159 unpackPremultiplyAlpha == GL_TRUE,
3160 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3161}
3162
3163void Context::copySubTextureCHROMIUM(GLuint sourceId,
3164 GLuint destId,
3165 GLint xoffset,
3166 GLint yoffset,
3167 GLint x,
3168 GLint y,
3169 GLsizei width,
3170 GLsizei height,
3171 GLboolean unpackFlipY,
3172 GLboolean unpackPremultiplyAlpha,
3173 GLboolean unpackUnmultiplyAlpha)
3174{
3175 // Zero sized copies are valid but no-ops
3176 if (width == 0 || height == 0)
3177 {
3178 return;
3179 }
3180
3181 syncStateForTexImage();
3182
3183 gl::Texture *sourceTexture = getTexture(sourceId);
3184 gl::Texture *destTexture = getTexture(destId);
3185 Offset offset(xoffset, yoffset, 0);
3186 Rectangle area(x, y, width, height);
Jamie Madill8897afa2017-02-06 17:17:23 -05003187 handleError(destTexture->copySubTexture(this, offset, area, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003188 unpackPremultiplyAlpha == GL_TRUE,
3189 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3190}
3191
Geoff Lang47110bf2016-04-20 11:13:22 -07003192void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3193{
3194 syncStateForTexImage();
3195
3196 gl::Texture *sourceTexture = getTexture(sourceId);
3197 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003198 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003199}
3200
Geoff Lang496c02d2016-10-20 11:38:11 -07003201void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003202{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003203 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003204 ASSERT(buffer);
3205
Geoff Lang496c02d2016-10-20 11:38:11 -07003206 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003207}
3208
3209GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3210{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003211 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003212 ASSERT(buffer);
3213
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003214 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003215 if (error.isError())
3216 {
Jamie Madill437fa652016-05-03 15:13:24 -04003217 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003218 return nullptr;
3219 }
3220
3221 return buffer->getMapPointer();
3222}
3223
3224GLboolean Context::unmapBuffer(GLenum target)
3225{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003226 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003227 ASSERT(buffer);
3228
3229 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003230 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003231 if (error.isError())
3232 {
Jamie Madill437fa652016-05-03 15:13:24 -04003233 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003234 return GL_FALSE;
3235 }
3236
3237 return result;
3238}
3239
3240GLvoid *Context::mapBufferRange(GLenum target,
3241 GLintptr offset,
3242 GLsizeiptr length,
3243 GLbitfield access)
3244{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003245 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003246 ASSERT(buffer);
3247
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003248 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003249 if (error.isError())
3250 {
Jamie Madill437fa652016-05-03 15:13:24 -04003251 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003252 return nullptr;
3253 }
3254
3255 return buffer->getMapPointer();
3256}
3257
3258void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3259{
3260 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3261}
3262
Jamie Madillad9f24e2016-02-12 09:27:24 -05003263void Context::syncStateForReadPixels()
3264{
3265 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3266}
3267
3268void Context::syncStateForTexImage()
3269{
3270 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3271}
3272
3273void Context::syncStateForClear()
3274{
3275 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3276}
3277
3278void Context::syncStateForBlit()
3279{
3280 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3281}
3282
Jamie Madillc20ab272016-06-09 07:20:46 -07003283void Context::activeTexture(GLenum texture)
3284{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003285 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003286}
3287
3288void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3289{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003290 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003291}
3292
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003293void Context::blendEquation(GLenum mode)
3294{
3295 mGLState.setBlendEquation(mode, mode);
3296}
3297
Jamie Madillc20ab272016-06-09 07:20:46 -07003298void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3299{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003300 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003301}
3302
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003303void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3304{
3305 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3306}
3307
Jamie Madillc20ab272016-06-09 07:20:46 -07003308void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3309{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003310 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003311}
3312
3313void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3314{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003315 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003316}
3317
3318void Context::clearDepthf(GLclampf depth)
3319{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003320 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003321}
3322
3323void Context::clearStencil(GLint s)
3324{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003325 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003326}
3327
3328void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3329{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003330 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003331}
3332
3333void Context::cullFace(GLenum mode)
3334{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003335 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003336}
3337
3338void Context::depthFunc(GLenum func)
3339{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003340 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003341}
3342
3343void Context::depthMask(GLboolean flag)
3344{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003345 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003346}
3347
3348void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3349{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003350 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003351}
3352
3353void Context::disable(GLenum cap)
3354{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003355 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003356}
3357
3358void Context::disableVertexAttribArray(GLuint index)
3359{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003360 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003361}
3362
3363void Context::enable(GLenum cap)
3364{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003365 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003366}
3367
3368void Context::enableVertexAttribArray(GLuint index)
3369{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003370 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003371}
3372
3373void Context::frontFace(GLenum mode)
3374{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003375 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003376}
3377
3378void Context::hint(GLenum target, GLenum mode)
3379{
3380 switch (target)
3381 {
3382 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003383 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003384 break;
3385
3386 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003387 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003388 break;
3389
3390 default:
3391 UNREACHABLE();
3392 return;
3393 }
3394}
3395
3396void Context::lineWidth(GLfloat width)
3397{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003398 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003399}
3400
3401void Context::pixelStorei(GLenum pname, GLint param)
3402{
3403 switch (pname)
3404 {
3405 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003406 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003407 break;
3408
3409 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003410 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003411 break;
3412
3413 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003414 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003415 break;
3416
3417 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003418 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420 break;
3421
3422 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003423 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425 break;
3426
3427 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003428 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003429 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003430 break;
3431
3432 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003433 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003434 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003435 break;
3436
3437 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003438 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003439 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003440 break;
3441
3442 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003443 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003444 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003445 break;
3446
3447 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003448 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003449 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003450 break;
3451
3452 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003453 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003454 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003455 break;
3456
3457 default:
3458 UNREACHABLE();
3459 return;
3460 }
3461}
3462
3463void Context::polygonOffset(GLfloat factor, GLfloat units)
3464{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003466}
3467
3468void Context::sampleCoverage(GLclampf value, GLboolean invert)
3469{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003470 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003471}
3472
3473void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3474{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003475 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003476}
3477
3478void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3479{
3480 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3481 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003482 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003483 }
3484
3485 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3486 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003487 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003488 }
3489}
3490
3491void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3492{
3493 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3494 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003495 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003496 }
3497
3498 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3499 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003500 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003501 }
3502}
3503
3504void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3505{
3506 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3507 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003509 }
3510
3511 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3512 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003513 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003514 }
3515}
3516
3517void Context::vertexAttrib1f(GLuint index, GLfloat x)
3518{
3519 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
3523void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3524{
3525 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003526 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003527}
3528
3529void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3530{
3531 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003532 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003533}
3534
3535void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3536{
3537 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003538 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003539}
3540
3541void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3542{
3543 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003545}
3546
3547void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3548{
3549 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003551}
3552
3553void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3554{
3555 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003556 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003557}
3558
3559void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3560{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003561 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003562}
3563
3564void Context::vertexAttribPointer(GLuint index,
3565 GLint size,
3566 GLenum type,
3567 GLboolean normalized,
3568 GLsizei stride,
3569 const GLvoid *ptr)
3570{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003571 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3572 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003573}
3574
3575void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3576{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003577 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003578}
3579
3580void Context::vertexAttribIPointer(GLuint index,
3581 GLint size,
3582 GLenum type,
3583 GLsizei stride,
3584 const GLvoid *pointer)
3585{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003586 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3587 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003588}
3589
3590void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3591{
3592 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003593 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003594}
3595
3596void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3597{
3598 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003599 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003600}
3601
3602void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3603{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003604 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003605}
3606
3607void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3608{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003609 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003610}
3611
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003612void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3613{
3614 const VertexAttribCurrentValueData &currentValues =
3615 getGLState().getVertexAttribCurrentValue(index);
3616 const VertexArray *vao = getGLState().getVertexArray();
3617 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3618 currentValues, pname, params);
3619}
3620
3621void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3622{
3623 const VertexAttribCurrentValueData &currentValues =
3624 getGLState().getVertexAttribCurrentValue(index);
3625 const VertexArray *vao = getGLState().getVertexArray();
3626 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3627 currentValues, pname, params);
3628}
3629
3630void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3631{
3632 const VertexAttribCurrentValueData &currentValues =
3633 getGLState().getVertexAttribCurrentValue(index);
3634 const VertexArray *vao = getGLState().getVertexArray();
3635 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3636 currentValues, pname, params);
3637}
3638
3639void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3640{
3641 const VertexAttribCurrentValueData &currentValues =
3642 getGLState().getVertexAttribCurrentValue(index);
3643 const VertexArray *vao = getGLState().getVertexArray();
3644 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3645 currentValues, pname, params);
3646}
3647
3648void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3649{
3650 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3651 QueryVertexAttribPointerv(attrib, pname, pointer);
3652}
3653
Jamie Madillc20ab272016-06-09 07:20:46 -07003654void Context::debugMessageControl(GLenum source,
3655 GLenum type,
3656 GLenum severity,
3657 GLsizei count,
3658 const GLuint *ids,
3659 GLboolean enabled)
3660{
3661 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003662 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3663 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003664}
3665
3666void Context::debugMessageInsert(GLenum source,
3667 GLenum type,
3668 GLuint id,
3669 GLenum severity,
3670 GLsizei length,
3671 const GLchar *buf)
3672{
3673 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003674 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003675}
3676
3677void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3678{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003679 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003680}
3681
3682GLuint Context::getDebugMessageLog(GLuint count,
3683 GLsizei bufSize,
3684 GLenum *sources,
3685 GLenum *types,
3686 GLuint *ids,
3687 GLenum *severities,
3688 GLsizei *lengths,
3689 GLchar *messageLog)
3690{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003691 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3692 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003693}
3694
3695void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3696{
3697 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003698 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003699}
3700
3701void Context::popDebugGroup()
3702{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003703 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003704}
3705
Jamie Madill29639852016-09-02 15:00:09 -04003706void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3707{
3708 Buffer *buffer = mGLState.getTargetBuffer(target);
3709 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003710 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003711}
3712
3713void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3714{
3715 if (data == nullptr)
3716 {
3717 return;
3718 }
3719
3720 Buffer *buffer = mGLState.getTargetBuffer(target);
3721 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003722 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003723}
3724
Jamie Madillef300b12016-10-07 15:12:09 -04003725void Context::attachShader(GLuint program, GLuint shader)
3726{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003727 auto programObject = mState.mShaderPrograms->getProgram(program);
3728 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003729 ASSERT(programObject && shaderObject);
3730 programObject->attachShader(shaderObject);
3731}
3732
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003733const Workarounds &Context::getWorkarounds() const
3734{
3735 return mWorkarounds;
3736}
3737
Jamie Madillb0817d12016-11-01 15:48:31 -04003738void Context::copyBufferSubData(GLenum readTarget,
3739 GLenum writeTarget,
3740 GLintptr readOffset,
3741 GLintptr writeOffset,
3742 GLsizeiptr size)
3743{
3744 // if size is zero, the copy is a successful no-op
3745 if (size == 0)
3746 {
3747 return;
3748 }
3749
3750 // TODO(jmadill): cache these.
3751 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3752 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3753
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003754 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003755}
3756
Jamie Madill01a80ee2016-11-07 12:06:18 -05003757void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3758{
3759 Program *programObject = getProgram(program);
3760 // TODO(jmadill): Re-use this from the validation if possible.
3761 ASSERT(programObject);
3762 programObject->bindAttributeLocation(index, name);
3763}
3764
3765void Context::bindBuffer(GLenum target, GLuint buffer)
3766{
3767 switch (target)
3768 {
3769 case GL_ARRAY_BUFFER:
3770 bindArrayBuffer(buffer);
3771 break;
3772 case GL_ELEMENT_ARRAY_BUFFER:
3773 bindElementArrayBuffer(buffer);
3774 break;
3775 case GL_COPY_READ_BUFFER:
3776 bindCopyReadBuffer(buffer);
3777 break;
3778 case GL_COPY_WRITE_BUFFER:
3779 bindCopyWriteBuffer(buffer);
3780 break;
3781 case GL_PIXEL_PACK_BUFFER:
3782 bindPixelPackBuffer(buffer);
3783 break;
3784 case GL_PIXEL_UNPACK_BUFFER:
3785 bindPixelUnpackBuffer(buffer);
3786 break;
3787 case GL_UNIFORM_BUFFER:
3788 bindGenericUniformBuffer(buffer);
3789 break;
3790 case GL_TRANSFORM_FEEDBACK_BUFFER:
3791 bindGenericTransformFeedbackBuffer(buffer);
3792 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003793 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003794 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003795 break;
3796 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003797 if (buffer != 0)
3798 {
3799 // Binding buffers to this binding point is not implemented yet.
3800 UNIMPLEMENTED();
3801 }
Geoff Lang3b573612016-10-31 14:08:10 -04003802 break;
3803 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003804 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003805 break;
3806 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003807 if (buffer != 0)
3808 {
3809 // Binding buffers to this binding point is not implemented yet.
3810 UNIMPLEMENTED();
3811 }
Geoff Lang3b573612016-10-31 14:08:10 -04003812 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003813
3814 default:
3815 UNREACHABLE();
3816 break;
3817 }
3818}
3819
Jiajia Qin6eafb042016-12-27 17:04:07 +08003820void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3821{
3822 bindBufferRange(target, index, buffer, 0, 0);
3823}
3824
3825void Context::bindBufferRange(GLenum target,
3826 GLuint index,
3827 GLuint buffer,
3828 GLintptr offset,
3829 GLsizeiptr size)
3830{
3831 switch (target)
3832 {
3833 case GL_TRANSFORM_FEEDBACK_BUFFER:
3834 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3835 bindGenericTransformFeedbackBuffer(buffer);
3836 break;
3837 case GL_UNIFORM_BUFFER:
3838 bindIndexedUniformBuffer(buffer, index, offset, size);
3839 bindGenericUniformBuffer(buffer);
3840 break;
3841 case GL_ATOMIC_COUNTER_BUFFER:
3842 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3843 bindGenericAtomicCounterBuffer(buffer);
3844 break;
3845 case GL_SHADER_STORAGE_BUFFER:
3846 if (buffer != 0)
3847 {
3848 // Binding buffers to this binding point is not implemented yet.
3849 UNIMPLEMENTED();
3850 }
3851 break;
3852 default:
3853 UNREACHABLE();
3854 break;
3855 }
3856}
3857
Jamie Madill01a80ee2016-11-07 12:06:18 -05003858void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3859{
3860 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3861 {
3862 bindReadFramebuffer(framebuffer);
3863 }
3864
3865 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3866 {
3867 bindDrawFramebuffer(framebuffer);
3868 }
3869}
3870
3871void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3872{
3873 ASSERT(target == GL_RENDERBUFFER);
3874 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003875 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003876 mGLState.setRenderbufferBinding(object);
3877}
3878
JiangYizhoubddc46b2016-12-09 09:50:51 +08003879void Context::texStorage2DMultisample(GLenum target,
3880 GLsizei samples,
3881 GLenum internalformat,
3882 GLsizei width,
3883 GLsizei height,
3884 GLboolean fixedsamplelocations)
3885{
3886 Extents size(width, height, 1);
3887 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003888 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003889 fixedsamplelocations));
3890}
3891
3892void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3893{
3894 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3895 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3896
3897 switch (pname)
3898 {
3899 case GL_SAMPLE_POSITION:
3900 handleError(framebuffer->getSamplePosition(index, val));
3901 break;
3902 default:
3903 UNREACHABLE();
3904 }
3905}
3906
Jamie Madille8fb6402017-02-14 17:56:40 -05003907void Context::renderbufferStorage(GLenum target,
3908 GLenum internalformat,
3909 GLsizei width,
3910 GLsizei height)
3911{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003912 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3913 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3914
Jamie Madille8fb6402017-02-14 17:56:40 -05003915 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003916 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003917}
3918
3919void Context::renderbufferStorageMultisample(GLenum target,
3920 GLsizei samples,
3921 GLenum internalformat,
3922 GLsizei width,
3923 GLsizei height)
3924{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003925 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3926 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05003927
3928 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003929 handleError(
3930 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003931}
3932
JiangYizhoue18e6392017-02-20 10:32:23 +08003933void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
3934{
3935 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3936 QueryFramebufferParameteriv(framebuffer, pname, params);
3937}
3938
3939void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
3940{
3941 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3942 SetFramebufferParameteri(framebuffer, pname, param);
3943}
3944
Jamie Madille14951e2017-03-09 18:55:16 -05003945Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
3946{
3947 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
3948 {
3949 return gl::OutOfMemory() << "Failed to allocate internal buffer.";
3950 }
3951 return gl::NoError();
3952}
3953
Jamie Madillc29968b2016-01-20 11:17:23 -05003954} // namespace gl