blob: 1c31951b3835f4dfdb853e6b6490f2ea9e69cfc5 [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
jchen1015015f72017-03-16 13:54:21 +08002041GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2042{
2043 gl::Program *programObject = getProgram(program);
2044 return QueryProgramResourceIndex(programObject, programInterface, name);
2045}
2046
Jamie Madill437fa652016-05-03 15:13:24 -04002047void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002048{
Geoff Langda5777c2014-07-11 09:52:58 -04002049 if (error.isError())
2050 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002051 GLenum code = error.getCode();
2052 mErrors.insert(code);
2053 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2054 {
2055 markContextLost();
2056 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002057
2058 if (!error.getMessage().empty())
2059 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002060 auto *debug = &mGLState.getDebug();
2061 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2062 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002063 }
Geoff Langda5777c2014-07-11 09:52:58 -04002064 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002065}
2066
2067// Get one of the recorded errors and clear its flag, if any.
2068// [OpenGL ES 2.0.24] section 2.5 page 13.
2069GLenum Context::getError()
2070{
Geoff Langda5777c2014-07-11 09:52:58 -04002071 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002072 {
Geoff Langda5777c2014-07-11 09:52:58 -04002073 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002074 }
Geoff Langda5777c2014-07-11 09:52:58 -04002075 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002076 {
Geoff Langda5777c2014-07-11 09:52:58 -04002077 GLenum error = *mErrors.begin();
2078 mErrors.erase(mErrors.begin());
2079 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002080 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002081}
2082
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002083// NOTE: this function should not assume that this context is current!
2084void Context::markContextLost()
2085{
2086 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002087 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002088 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002089 mContextLostForced = true;
2090 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002091 mContextLost = true;
2092}
2093
2094bool Context::isContextLost()
2095{
2096 return mContextLost;
2097}
2098
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002099GLenum Context::getResetStatus()
2100{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002101 // Even if the application doesn't want to know about resets, we want to know
2102 // as it will allow us to skip all the calls.
2103 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002104 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002105 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002106 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002107 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002108 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002109
2110 // EXT_robustness, section 2.6: If the reset notification behavior is
2111 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2112 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2113 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002114 }
2115
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002116 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2117 // status should be returned at least once, and GL_NO_ERROR should be returned
2118 // once the device has finished resetting.
2119 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002120 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002121 ASSERT(mResetStatus == GL_NO_ERROR);
2122 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002123
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002124 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002125 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002126 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002127 }
2128 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002129 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002130 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002131 // If markContextLost was used to mark the context lost then
2132 // assume that is not recoverable, and continue to report the
2133 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002134 mResetStatus = mImplementation->getResetStatus();
2135 }
Jamie Madill893ab082014-05-16 16:56:10 -04002136
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002137 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002138}
2139
2140bool Context::isResetNotificationEnabled()
2141{
2142 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2143}
2144
Corentin Walleze3b10e82015-05-20 11:06:25 -04002145const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002146{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002147 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002148}
2149
2150EGLenum Context::getClientType() const
2151{
2152 return mClientType;
2153}
2154
2155EGLenum Context::getRenderBuffer() const
2156{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002157 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2158 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002159 {
2160 return EGL_NONE;
2161 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002162
2163 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2164 ASSERT(backAttachment != nullptr);
2165 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002166}
2167
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002168VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002169{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002170 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002171 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2172 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002173 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002174 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2175 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002176
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002177 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002178 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002179
2180 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002181}
2182
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002183TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002184{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002185 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002186 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2187 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002188 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002189 transformFeedback =
2190 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002191 transformFeedback->addRef();
2192 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002193 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002194
2195 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002196}
2197
2198bool Context::isVertexArrayGenerated(GLuint vertexArray)
2199{
Geoff Langf41a7152016-09-19 15:11:17 -04002200 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002201 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2202}
2203
2204bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2205{
Geoff Langf41a7152016-09-19 15:11:17 -04002206 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002207 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2208}
2209
Shannon Woods53a94a82014-06-24 15:20:36 -04002210void Context::detachTexture(GLuint texture)
2211{
2212 // Simple pass-through to State's detachTexture method, as textures do not require
2213 // allocation map management either here or in the resource manager at detach time.
2214 // Zero textures are held by the Context, and we don't attempt to request them from
2215 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002216 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002217}
2218
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002219void Context::detachBuffer(GLuint buffer)
2220{
Yuly Novikov5807a532015-12-03 13:01:22 -05002221 // Simple pass-through to State's detachBuffer method, since
2222 // only buffer attachments to container objects that are bound to the current context
2223 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002224
Yuly Novikov5807a532015-12-03 13:01:22 -05002225 // [OpenGL ES 3.2] section 5.1.2 page 45:
2226 // Attachments to unbound container objects, such as
2227 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2228 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002229 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002230}
2231
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002232void Context::detachFramebuffer(GLuint framebuffer)
2233{
Shannon Woods53a94a82014-06-24 15:20:36 -04002234 // Framebuffer detachment is handled by Context, because 0 is a valid
2235 // Framebuffer object, and a pointer to it must be passed from Context
2236 // to State at binding time.
2237
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002238 // [OpenGL ES 2.0.24] section 4.4 page 107:
2239 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2240 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2241
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002242 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002243 {
2244 bindReadFramebuffer(0);
2245 }
2246
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002247 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002248 {
2249 bindDrawFramebuffer(0);
2250 }
2251}
2252
2253void Context::detachRenderbuffer(GLuint renderbuffer)
2254{
Jamie Madilla02315b2017-02-23 14:14:47 -05002255 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002256}
2257
Jamie Madill57a89722013-07-02 11:57:03 -04002258void Context::detachVertexArray(GLuint vertexArray)
2259{
Jamie Madill77a72f62015-04-14 11:18:32 -04002260 // Vertex array detachment is handled by Context, because 0 is a valid
2261 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002262 // binding time.
2263
Jamie Madill57a89722013-07-02 11:57:03 -04002264 // [OpenGL ES 3.0.2] section 2.10 page 43:
2265 // If a vertex array object that is currently bound is deleted, the binding
2266 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002267 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002268 {
2269 bindVertexArray(0);
2270 }
2271}
2272
Geoff Langc8058452014-02-03 12:04:11 -05002273void Context::detachTransformFeedback(GLuint transformFeedback)
2274{
Corentin Walleza2257da2016-04-19 16:43:12 -04002275 // Transform feedback detachment is handled by Context, because 0 is a valid
2276 // transform feedback, and a pointer to it must be passed from Context to State at
2277 // binding time.
2278
2279 // The OpenGL specification doesn't mention what should happen when the currently bound
2280 // transform feedback object is deleted. Since it is a container object, we treat it like
2281 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002282 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002283 {
2284 bindTransformFeedback(0);
2285 }
Geoff Langc8058452014-02-03 12:04:11 -05002286}
2287
Jamie Madilldc356042013-07-19 16:36:57 -04002288void Context::detachSampler(GLuint sampler)
2289{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002290 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002291}
2292
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002293void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2294{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002295 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002296}
2297
Jamie Madille29d1672013-07-19 16:36:57 -04002298void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2299{
Geoff Langc1984ed2016-10-07 12:41:00 -04002300 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002301 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002302 SetSamplerParameteri(samplerObject, pname, param);
2303}
Jamie Madille29d1672013-07-19 16:36:57 -04002304
Geoff Langc1984ed2016-10-07 12:41:00 -04002305void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2306{
2307 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002308 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002309 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002310}
2311
2312void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2313{
Geoff Langc1984ed2016-10-07 12:41:00 -04002314 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002315 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002316 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002317}
2318
Geoff Langc1984ed2016-10-07 12:41:00 -04002319void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002320{
Geoff Langc1984ed2016-10-07 12:41:00 -04002321 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002322 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002323 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002324}
2325
Geoff Langc1984ed2016-10-07 12:41:00 -04002326void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002327{
Geoff Langc1984ed2016-10-07 12:41:00 -04002328 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002329 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002330 QuerySamplerParameteriv(samplerObject, pname, params);
2331}
Jamie Madill9675b802013-07-19 16:36:59 -04002332
Geoff Langc1984ed2016-10-07 12:41:00 -04002333void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2334{
2335 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002336 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002337 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002338}
2339
Olli Etuahof0fee072016-03-30 15:11:58 +03002340void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2341{
2342 gl::Program *programObject = getProgram(program);
2343 ASSERT(programObject != nullptr);
2344
2345 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2346 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2347}
2348
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002349void Context::initRendererString()
2350{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002351 std::ostringstream rendererString;
2352 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002353 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002354 rendererString << ")";
2355
Geoff Langcec35902014-04-16 10:52:36 -04002356 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002357}
2358
Geoff Langc339c4e2016-11-29 10:37:36 -05002359void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002360{
Geoff Langc339c4e2016-11-29 10:37:36 -05002361 const Version &clientVersion = getClientVersion();
2362
2363 std::ostringstream versionString;
2364 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2365 << ANGLE_VERSION_STRING << ")";
2366 mVersionString = MakeStaticString(versionString.str());
2367
2368 std::ostringstream shadingLanguageVersionString;
2369 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2370 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2371 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2372 << ")";
2373 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002374}
2375
Geoff Langcec35902014-04-16 10:52:36 -04002376void Context::initExtensionStrings()
2377{
Geoff Langc339c4e2016-11-29 10:37:36 -05002378 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2379 std::ostringstream combinedStringStream;
2380 std::copy(strings.begin(), strings.end(),
2381 std::ostream_iterator<const char *>(combinedStringStream, " "));
2382 return MakeStaticString(combinedStringStream.str());
2383 };
2384
2385 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002386 for (const auto &extensionString : mExtensions.getStrings())
2387 {
2388 mExtensionStrings.push_back(MakeStaticString(extensionString));
2389 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002390 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002391
Bryan Bernhart58806562017-01-05 13:09:31 -08002392 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2393
Geoff Langc339c4e2016-11-29 10:37:36 -05002394 mRequestableExtensionStrings.clear();
2395 for (const auto &extensionInfo : GetExtensionInfoMap())
2396 {
2397 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002398 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2399 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002400 {
2401 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2402 }
2403 }
2404 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002405}
2406
Geoff Langc339c4e2016-11-29 10:37:36 -05002407const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002408{
Geoff Langc339c4e2016-11-29 10:37:36 -05002409 switch (name)
2410 {
2411 case GL_VENDOR:
2412 return reinterpret_cast<const GLubyte *>("Google Inc.");
2413
2414 case GL_RENDERER:
2415 return reinterpret_cast<const GLubyte *>(mRendererString);
2416
2417 case GL_VERSION:
2418 return reinterpret_cast<const GLubyte *>(mVersionString);
2419
2420 case GL_SHADING_LANGUAGE_VERSION:
2421 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2422
2423 case GL_EXTENSIONS:
2424 return reinterpret_cast<const GLubyte *>(mExtensionString);
2425
2426 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2427 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2428
2429 default:
2430 UNREACHABLE();
2431 return nullptr;
2432 }
Geoff Langcec35902014-04-16 10:52:36 -04002433}
2434
Geoff Langc339c4e2016-11-29 10:37:36 -05002435const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002436{
Geoff Langc339c4e2016-11-29 10:37:36 -05002437 switch (name)
2438 {
2439 case GL_EXTENSIONS:
2440 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2441
2442 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2443 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2444
2445 default:
2446 UNREACHABLE();
2447 return nullptr;
2448 }
Geoff Langcec35902014-04-16 10:52:36 -04002449}
2450
2451size_t Context::getExtensionStringCount() const
2452{
2453 return mExtensionStrings.size();
2454}
2455
Geoff Langc339c4e2016-11-29 10:37:36 -05002456void Context::requestExtension(const char *name)
2457{
2458 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2459 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2460 const auto &extension = extensionInfos.at(name);
2461 ASSERT(extension.Requestable);
2462
2463 if (mExtensions.*(extension.ExtensionsMember))
2464 {
2465 // Extension already enabled
2466 return;
2467 }
2468
2469 mExtensions.*(extension.ExtensionsMember) = true;
2470 updateCaps();
2471 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002472
2473 // Re-create the compiler with the requested extensions enabled.
2474 SafeDelete(mCompiler);
2475 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002476}
2477
2478size_t Context::getRequestableExtensionStringCount() const
2479{
2480 return mRequestableExtensionStrings.size();
2481}
2482
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002483void Context::beginTransformFeedback(GLenum primitiveMode)
2484{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002485 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002486 ASSERT(transformFeedback != nullptr);
2487 ASSERT(!transformFeedback->isPaused());
2488
Jamie Madill6c1f6712017-02-14 19:08:04 -05002489 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002490}
2491
2492bool Context::hasActiveTransformFeedback(GLuint program) const
2493{
2494 for (auto pair : mTransformFeedbackMap)
2495 {
2496 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2497 {
2498 return true;
2499 }
2500 }
2501 return false;
2502}
2503
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002504void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002505{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002506 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002507
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002508 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002509
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002510 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002511
Geoff Langeb66a6e2016-10-31 13:06:12 -04002512 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002513 {
2514 // Disable ES3+ extensions
2515 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002516 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002517 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002518 }
2519
Geoff Langeb66a6e2016-10-31 13:06:12 -04002520 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002521 {
2522 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2523 //mExtensions.sRGB = false;
2524 }
2525
Jamie Madill00ed7a12016-05-19 13:13:38 -04002526 // Some extensions are always available because they are implemented in the GL layer.
2527 mExtensions.bindUniformLocation = true;
2528 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002529 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002530 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002531 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002532
2533 // Enable the no error extension if the context was created with the flag.
2534 mExtensions.noError = mSkipValidation;
2535
Corentin Wallezccab69d2017-01-27 16:57:15 -05002536 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002537 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002538
Geoff Lang70d0f492015-12-10 17:45:46 -05002539 // Explicitly enable GL_KHR_debug
2540 mExtensions.debug = true;
2541 mExtensions.maxDebugMessageLength = 1024;
2542 mExtensions.maxDebugLoggedMessages = 1024;
2543 mExtensions.maxDebugGroupStackDepth = 1024;
2544 mExtensions.maxLabelLength = 1024;
2545
Geoff Langff5b2d52016-09-07 11:32:23 -04002546 // Explicitly enable GL_ANGLE_robust_client_memory
2547 mExtensions.robustClientMemory = true;
2548
Jamie Madille08a1d32017-03-07 17:24:06 -05002549 // Determine robust resource init availability from EGL.
2550 mExtensions.robustResourceInitialization =
2551 displayExtensions.createContextRobustResourceInitialization;
2552
Geoff Lang301d1612014-07-09 10:34:37 -04002553 // Apply implementation limits
2554 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002555 mCaps.maxVertexAttribBindings =
2556 getClientVersion() < ES_3_1
2557 ? mCaps.maxVertexAttributes
2558 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2559
Geoff Lang301d1612014-07-09 10:34:37 -04002560 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2561 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2562
2563 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002564
Geoff Langc287ea62016-09-16 14:46:51 -04002565 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002566 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002567 for (const auto &extensionInfo : GetExtensionInfoMap())
2568 {
2569 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002570 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002571 {
2572 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2573 }
2574 }
2575
2576 // Generate texture caps
2577 updateCaps();
2578}
2579
2580void Context::updateCaps()
2581{
Geoff Lang900013c2014-07-07 11:32:19 -04002582 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002583 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002584
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002585 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002586 {
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002587 GLenum format = capsIt.first;
2588 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002589
Geoff Lang5d601382014-07-22 15:14:06 -04002590 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002591
Geoff Lang0d8b7242015-09-09 14:56:53 -04002592 // Update the format caps based on the client version and extensions.
2593 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2594 // ES3.
2595 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002596 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002597 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002598 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002599 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002600 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002601
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002602 // OpenGL ES does not support multisampling with non-rendererable formats
2603 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2604 if (!formatInfo.renderSupport ||
2605 (getClientVersion() < ES_3_1 &&
2606 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002607 {
Geoff Langd87878e2014-09-19 15:42:59 -04002608 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002609 }
Geoff Langd87878e2014-09-19 15:42:59 -04002610
2611 if (formatCaps.texturable && formatInfo.compressed)
2612 {
2613 mCaps.compressedTextureFormats.push_back(format);
2614 }
2615
2616 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002617 }
2618}
2619
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002620void Context::initWorkarounds()
2621{
2622 // Lose the context upon out of memory error if the application is
2623 // expecting to watch for those events.
2624 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2625}
2626
Jamie Madill1b94d432015-08-07 13:23:23 -04002627void Context::syncRendererState()
2628{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002629 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002630 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002631 mGLState.clearDirtyBits();
2632 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002633}
2634
Jamie Madillad9f24e2016-02-12 09:27:24 -05002635void Context::syncRendererState(const State::DirtyBits &bitMask,
2636 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002637{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002638 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002639 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002640 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002641
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002642 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002643}
Jamie Madillc29968b2016-01-20 11:17:23 -05002644
2645void Context::blitFramebuffer(GLint srcX0,
2646 GLint srcY0,
2647 GLint srcX1,
2648 GLint srcY1,
2649 GLint dstX0,
2650 GLint dstY0,
2651 GLint dstX1,
2652 GLint dstY1,
2653 GLbitfield mask,
2654 GLenum filter)
2655{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002656 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002657 ASSERT(drawFramebuffer);
2658
2659 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2660 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2661
Jamie Madillad9f24e2016-02-12 09:27:24 -05002662 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002663
Jamie Madill8415b5f2016-04-26 13:41:39 -04002664 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002665}
Jamie Madillc29968b2016-01-20 11:17:23 -05002666
2667void Context::clear(GLbitfield mask)
2668{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002669 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002670 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002671}
2672
2673void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2674{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002675 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002676 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2677 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002678}
2679
2680void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2681{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002682 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002683 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2684 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002685}
2686
2687void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2688{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002689 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002690 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2691 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002692}
2693
2694void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2695{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002696 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002697 ASSERT(framebufferObject);
2698
2699 // If a buffer is not present, the clear has no effect
2700 if (framebufferObject->getDepthbuffer() == nullptr &&
2701 framebufferObject->getStencilbuffer() == nullptr)
2702 {
2703 return;
2704 }
2705
Jamie Madillad9f24e2016-02-12 09:27:24 -05002706 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002707 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2708 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002709}
2710
2711void Context::readPixels(GLint x,
2712 GLint y,
2713 GLsizei width,
2714 GLsizei height,
2715 GLenum format,
2716 GLenum type,
2717 GLvoid *pixels)
2718{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002719 if (width == 0 || height == 0)
2720 {
2721 return;
2722 }
2723
Jamie Madillad9f24e2016-02-12 09:27:24 -05002724 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002725
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002726 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002727 ASSERT(framebufferObject);
2728
2729 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002730 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002731}
2732
2733void Context::copyTexImage2D(GLenum target,
2734 GLint level,
2735 GLenum internalformat,
2736 GLint x,
2737 GLint y,
2738 GLsizei width,
2739 GLsizei height,
2740 GLint border)
2741{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002742 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002743 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002744
Jamie Madillc29968b2016-01-20 11:17:23 -05002745 Rectangle sourceArea(x, y, width, height);
2746
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002747 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002748 Texture *texture =
2749 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002750 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002751}
2752
2753void Context::copyTexSubImage2D(GLenum target,
2754 GLint level,
2755 GLint xoffset,
2756 GLint yoffset,
2757 GLint x,
2758 GLint y,
2759 GLsizei width,
2760 GLsizei height)
2761{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002762 if (width == 0 || height == 0)
2763 {
2764 return;
2765 }
2766
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002767 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002768 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002769
Jamie Madillc29968b2016-01-20 11:17:23 -05002770 Offset destOffset(xoffset, yoffset, 0);
2771 Rectangle sourceArea(x, y, width, height);
2772
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002773 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002774 Texture *texture =
2775 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002776 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002777}
2778
2779void Context::copyTexSubImage3D(GLenum target,
2780 GLint level,
2781 GLint xoffset,
2782 GLint yoffset,
2783 GLint zoffset,
2784 GLint x,
2785 GLint y,
2786 GLsizei width,
2787 GLsizei height)
2788{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002789 if (width == 0 || height == 0)
2790 {
2791 return;
2792 }
2793
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002794 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002795 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002796
Jamie Madillc29968b2016-01-20 11:17:23 -05002797 Offset destOffset(xoffset, yoffset, zoffset);
2798 Rectangle sourceArea(x, y, width, height);
2799
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002800 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002801 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002802 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002803}
2804
2805void Context::framebufferTexture2D(GLenum target,
2806 GLenum attachment,
2807 GLenum textarget,
2808 GLuint texture,
2809 GLint level)
2810{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002811 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002812 ASSERT(framebuffer);
2813
2814 if (texture != 0)
2815 {
2816 Texture *textureObj = getTexture(texture);
2817
2818 ImageIndex index = ImageIndex::MakeInvalid();
2819
2820 if (textarget == GL_TEXTURE_2D)
2821 {
2822 index = ImageIndex::Make2D(level);
2823 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002824 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2825 {
2826 ASSERT(level == 0);
2827 index = ImageIndex::Make2DMultisample();
2828 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002829 else
2830 {
2831 ASSERT(IsCubeMapTextureTarget(textarget));
2832 index = ImageIndex::MakeCube(textarget, level);
2833 }
2834
Jamie Madilla02315b2017-02-23 14:14:47 -05002835 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002836 }
2837 else
2838 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002839 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002840 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002841
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002842 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002843}
2844
2845void Context::framebufferRenderbuffer(GLenum target,
2846 GLenum attachment,
2847 GLenum renderbuffertarget,
2848 GLuint renderbuffer)
2849{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002850 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002851 ASSERT(framebuffer);
2852
2853 if (renderbuffer != 0)
2854 {
2855 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002856
2857 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002858 renderbufferObject);
2859 }
2860 else
2861 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002862 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002863 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002864
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002865 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002866}
2867
2868void Context::framebufferTextureLayer(GLenum target,
2869 GLenum attachment,
2870 GLuint texture,
2871 GLint level,
2872 GLint layer)
2873{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002874 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002875 ASSERT(framebuffer);
2876
2877 if (texture != 0)
2878 {
2879 Texture *textureObject = getTexture(texture);
2880
2881 ImageIndex index = ImageIndex::MakeInvalid();
2882
2883 if (textureObject->getTarget() == GL_TEXTURE_3D)
2884 {
2885 index = ImageIndex::Make3D(level, layer);
2886 }
2887 else
2888 {
2889 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2890 index = ImageIndex::Make2DArray(level, layer);
2891 }
2892
Jamie Madilla02315b2017-02-23 14:14:47 -05002893 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002894 }
2895 else
2896 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002897 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002898 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002899
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002900 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002901}
2902
2903void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2904{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002905 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002906 ASSERT(framebuffer);
2907 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002908 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002909}
2910
2911void Context::readBuffer(GLenum mode)
2912{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002913 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002914 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002915 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002916}
2917
2918void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2919{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002920 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002921 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002922
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002923 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002924 ASSERT(framebuffer);
2925
2926 // The specification isn't clear what should be done when the framebuffer isn't complete.
2927 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002928 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002929}
2930
2931void Context::invalidateFramebuffer(GLenum target,
2932 GLsizei numAttachments,
2933 const GLenum *attachments)
2934{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002935 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002936 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002937
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002938 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002939 ASSERT(framebuffer);
2940
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002941 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002942 {
Jamie Madill437fa652016-05-03 15:13:24 -04002943 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002944 }
Jamie Madill437fa652016-05-03 15:13:24 -04002945
2946 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002947}
2948
2949void Context::invalidateSubFramebuffer(GLenum target,
2950 GLsizei numAttachments,
2951 const GLenum *attachments,
2952 GLint x,
2953 GLint y,
2954 GLsizei width,
2955 GLsizei height)
2956{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002957 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002958 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002959
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002960 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002961 ASSERT(framebuffer);
2962
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002963 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002964 {
Jamie Madill437fa652016-05-03 15:13:24 -04002965 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002966 }
Jamie Madill437fa652016-05-03 15:13:24 -04002967
2968 Rectangle area(x, y, width, height);
2969 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002970}
2971
Jamie Madill73a84962016-02-12 09:27:23 -05002972void Context::texImage2D(GLenum target,
2973 GLint level,
2974 GLint internalformat,
2975 GLsizei width,
2976 GLsizei height,
2977 GLint border,
2978 GLenum format,
2979 GLenum type,
2980 const GLvoid *pixels)
2981{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002982 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002983
2984 Extents size(width, height, 1);
2985 Texture *texture =
2986 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002987 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2988 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002989}
2990
2991void Context::texImage3D(GLenum target,
2992 GLint level,
2993 GLint internalformat,
2994 GLsizei width,
2995 GLsizei height,
2996 GLsizei depth,
2997 GLint border,
2998 GLenum format,
2999 GLenum type,
3000 const GLvoid *pixels)
3001{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003002 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003003
3004 Extents size(width, height, depth);
3005 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003006 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3007 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003008}
3009
3010void Context::texSubImage2D(GLenum target,
3011 GLint level,
3012 GLint xoffset,
3013 GLint yoffset,
3014 GLsizei width,
3015 GLsizei height,
3016 GLenum format,
3017 GLenum type,
3018 const GLvoid *pixels)
3019{
3020 // Zero sized uploads are valid but no-ops
3021 if (width == 0 || height == 0)
3022 {
3023 return;
3024 }
3025
Jamie Madillad9f24e2016-02-12 09:27:24 -05003026 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003027
3028 Box area(xoffset, yoffset, 0, width, height, 1);
3029 Texture *texture =
3030 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003031 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3032 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003033}
3034
3035void Context::texSubImage3D(GLenum target,
3036 GLint level,
3037 GLint xoffset,
3038 GLint yoffset,
3039 GLint zoffset,
3040 GLsizei width,
3041 GLsizei height,
3042 GLsizei depth,
3043 GLenum format,
3044 GLenum type,
3045 const GLvoid *pixels)
3046{
3047 // Zero sized uploads are valid but no-ops
3048 if (width == 0 || height == 0 || depth == 0)
3049 {
3050 return;
3051 }
3052
Jamie Madillad9f24e2016-02-12 09:27:24 -05003053 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003054
3055 Box area(xoffset, yoffset, zoffset, width, height, depth);
3056 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003057 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3058 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003059}
3060
3061void Context::compressedTexImage2D(GLenum target,
3062 GLint level,
3063 GLenum internalformat,
3064 GLsizei width,
3065 GLsizei height,
3066 GLint border,
3067 GLsizei imageSize,
3068 const GLvoid *data)
3069{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003070 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003071
3072 Extents size(width, height, 1);
3073 Texture *texture =
3074 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003075 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003076 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003077 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003078}
3079
3080void Context::compressedTexImage3D(GLenum target,
3081 GLint level,
3082 GLenum internalformat,
3083 GLsizei width,
3084 GLsizei height,
3085 GLsizei depth,
3086 GLint border,
3087 GLsizei imageSize,
3088 const GLvoid *data)
3089{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003090 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003091
3092 Extents size(width, height, depth);
3093 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003094 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003095 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003096 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003097}
3098
3099void Context::compressedTexSubImage2D(GLenum target,
3100 GLint level,
3101 GLint xoffset,
3102 GLint yoffset,
3103 GLsizei width,
3104 GLsizei height,
3105 GLenum format,
3106 GLsizei imageSize,
3107 const GLvoid *data)
3108{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003109 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003110
3111 Box area(xoffset, yoffset, 0, width, height, 1);
3112 Texture *texture =
3113 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003114 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003115 format, imageSize,
3116 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003117}
3118
3119void Context::compressedTexSubImage3D(GLenum target,
3120 GLint level,
3121 GLint xoffset,
3122 GLint yoffset,
3123 GLint zoffset,
3124 GLsizei width,
3125 GLsizei height,
3126 GLsizei depth,
3127 GLenum format,
3128 GLsizei imageSize,
3129 const GLvoid *data)
3130{
3131 // Zero sized uploads are valid but no-ops
3132 if (width == 0 || height == 0)
3133 {
3134 return;
3135 }
3136
Jamie Madillad9f24e2016-02-12 09:27:24 -05003137 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003138
3139 Box area(xoffset, yoffset, zoffset, width, height, depth);
3140 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003141 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003142 format, imageSize,
3143 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003144}
3145
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003146void Context::generateMipmap(GLenum target)
3147{
3148 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003149 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003150}
3151
Geoff Lang97073d12016-04-20 10:42:34 -07003152void Context::copyTextureCHROMIUM(GLuint sourceId,
3153 GLuint destId,
3154 GLint internalFormat,
3155 GLenum destType,
3156 GLboolean unpackFlipY,
3157 GLboolean unpackPremultiplyAlpha,
3158 GLboolean unpackUnmultiplyAlpha)
3159{
3160 syncStateForTexImage();
3161
3162 gl::Texture *sourceTexture = getTexture(sourceId);
3163 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003164 handleError(destTexture->copyTexture(this, internalFormat, destType, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003165 unpackPremultiplyAlpha == GL_TRUE,
3166 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3167}
3168
3169void Context::copySubTextureCHROMIUM(GLuint sourceId,
3170 GLuint destId,
3171 GLint xoffset,
3172 GLint yoffset,
3173 GLint x,
3174 GLint y,
3175 GLsizei width,
3176 GLsizei height,
3177 GLboolean unpackFlipY,
3178 GLboolean unpackPremultiplyAlpha,
3179 GLboolean unpackUnmultiplyAlpha)
3180{
3181 // Zero sized copies are valid but no-ops
3182 if (width == 0 || height == 0)
3183 {
3184 return;
3185 }
3186
3187 syncStateForTexImage();
3188
3189 gl::Texture *sourceTexture = getTexture(sourceId);
3190 gl::Texture *destTexture = getTexture(destId);
3191 Offset offset(xoffset, yoffset, 0);
3192 Rectangle area(x, y, width, height);
Jamie Madill8897afa2017-02-06 17:17:23 -05003193 handleError(destTexture->copySubTexture(this, offset, area, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003194 unpackPremultiplyAlpha == GL_TRUE,
3195 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3196}
3197
Geoff Lang47110bf2016-04-20 11:13:22 -07003198void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3199{
3200 syncStateForTexImage();
3201
3202 gl::Texture *sourceTexture = getTexture(sourceId);
3203 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003204 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003205}
3206
Geoff Lang496c02d2016-10-20 11:38:11 -07003207void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003208{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003209 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003210 ASSERT(buffer);
3211
Geoff Lang496c02d2016-10-20 11:38:11 -07003212 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003213}
3214
3215GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003217 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003218 ASSERT(buffer);
3219
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003220 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003221 if (error.isError())
3222 {
Jamie Madill437fa652016-05-03 15:13:24 -04003223 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003224 return nullptr;
3225 }
3226
3227 return buffer->getMapPointer();
3228}
3229
3230GLboolean Context::unmapBuffer(GLenum target)
3231{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003232 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003233 ASSERT(buffer);
3234
3235 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003236 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003237 if (error.isError())
3238 {
Jamie Madill437fa652016-05-03 15:13:24 -04003239 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003240 return GL_FALSE;
3241 }
3242
3243 return result;
3244}
3245
3246GLvoid *Context::mapBufferRange(GLenum target,
3247 GLintptr offset,
3248 GLsizeiptr length,
3249 GLbitfield access)
3250{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003251 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003252 ASSERT(buffer);
3253
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003254 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003255 if (error.isError())
3256 {
Jamie Madill437fa652016-05-03 15:13:24 -04003257 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003258 return nullptr;
3259 }
3260
3261 return buffer->getMapPointer();
3262}
3263
3264void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3265{
3266 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3267}
3268
Jamie Madillad9f24e2016-02-12 09:27:24 -05003269void Context::syncStateForReadPixels()
3270{
3271 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3272}
3273
3274void Context::syncStateForTexImage()
3275{
3276 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3277}
3278
3279void Context::syncStateForClear()
3280{
3281 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3282}
3283
3284void Context::syncStateForBlit()
3285{
3286 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3287}
3288
Jamie Madillc20ab272016-06-09 07:20:46 -07003289void Context::activeTexture(GLenum texture)
3290{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003291 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003292}
3293
3294void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3295{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003297}
3298
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003299void Context::blendEquation(GLenum mode)
3300{
3301 mGLState.setBlendEquation(mode, mode);
3302}
3303
Jamie Madillc20ab272016-06-09 07:20:46 -07003304void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3305{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003306 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003307}
3308
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003309void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3310{
3311 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3312}
3313
Jamie Madillc20ab272016-06-09 07:20:46 -07003314void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3315{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003316 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003317}
3318
3319void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3320{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003321 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003322}
3323
3324void Context::clearDepthf(GLclampf depth)
3325{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003326 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003327}
3328
3329void Context::clearStencil(GLint s)
3330{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003331 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003332}
3333
3334void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3335{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003336 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003337}
3338
3339void Context::cullFace(GLenum mode)
3340{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003341 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003342}
3343
3344void Context::depthFunc(GLenum func)
3345{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003346 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003347}
3348
3349void Context::depthMask(GLboolean flag)
3350{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003351 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003352}
3353
3354void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3355{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003356 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003357}
3358
3359void Context::disable(GLenum cap)
3360{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003361 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003362}
3363
3364void Context::disableVertexAttribArray(GLuint index)
3365{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003366 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003367}
3368
3369void Context::enable(GLenum cap)
3370{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003371 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003372}
3373
3374void Context::enableVertexAttribArray(GLuint index)
3375{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003376 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003377}
3378
3379void Context::frontFace(GLenum mode)
3380{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003381 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003382}
3383
3384void Context::hint(GLenum target, GLenum mode)
3385{
3386 switch (target)
3387 {
3388 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003390 break;
3391
3392 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003393 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003394 break;
3395
3396 default:
3397 UNREACHABLE();
3398 return;
3399 }
3400}
3401
3402void Context::lineWidth(GLfloat width)
3403{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003404 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003405}
3406
3407void Context::pixelStorei(GLenum pname, GLint param)
3408{
3409 switch (pname)
3410 {
3411 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003412 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003413 break;
3414
3415 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003416 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003417 break;
3418
3419 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003420 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003421 break;
3422
3423 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003424 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003425 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003426 break;
3427
3428 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003429 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003430 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003431 break;
3432
3433 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003434 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003435 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003436 break;
3437
3438 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003439 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003440 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003441 break;
3442
3443 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003444 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003445 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003446 break;
3447
3448 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003449 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003450 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003451 break;
3452
3453 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003454 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003455 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003456 break;
3457
3458 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003459 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003460 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003461 break;
3462
3463 default:
3464 UNREACHABLE();
3465 return;
3466 }
3467}
3468
3469void Context::polygonOffset(GLfloat factor, GLfloat units)
3470{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003471 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003472}
3473
3474void Context::sampleCoverage(GLclampf value, GLboolean invert)
3475{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003476 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003477}
3478
3479void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3480{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003481 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003482}
3483
3484void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3485{
3486 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3487 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003488 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003489 }
3490
3491 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3492 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003493 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003494 }
3495}
3496
3497void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3498{
3499 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3500 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003501 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003502 }
3503
3504 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3505 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003506 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003507 }
3508}
3509
3510void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3511{
3512 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3513 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003514 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003515 }
3516
3517 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3518 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003519 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003520 }
3521}
3522
3523void Context::vertexAttrib1f(GLuint index, GLfloat x)
3524{
3525 GLfloat vals[4] = {x, 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::vertexAttrib1fv(GLuint index, const GLfloat *values)
3530{
3531 GLfloat vals[4] = {values[0], 0, 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::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3536{
3537 GLfloat vals[4] = {x, y, 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::vertexAttrib2fv(GLuint index, const GLfloat *values)
3542{
3543 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003545}
3546
3547void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3548{
3549 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003551}
3552
3553void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3554{
3555 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003556 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003557}
3558
3559void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3560{
3561 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003562 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003563}
3564
3565void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3566{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003567 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003568}
3569
3570void Context::vertexAttribPointer(GLuint index,
3571 GLint size,
3572 GLenum type,
3573 GLboolean normalized,
3574 GLsizei stride,
3575 const GLvoid *ptr)
3576{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003577 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3578 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003579}
3580
3581void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3582{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003583 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003584}
3585
3586void Context::vertexAttribIPointer(GLuint index,
3587 GLint size,
3588 GLenum type,
3589 GLsizei stride,
3590 const GLvoid *pointer)
3591{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003592 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3593 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003594}
3595
3596void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3597{
3598 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003599 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003600}
3601
3602void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3603{
3604 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003605 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003606}
3607
3608void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3609{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003610 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003611}
3612
3613void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3614{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003615 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003616}
3617
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003618void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3619{
3620 const VertexAttribCurrentValueData &currentValues =
3621 getGLState().getVertexAttribCurrentValue(index);
3622 const VertexArray *vao = getGLState().getVertexArray();
3623 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3624 currentValues, pname, params);
3625}
3626
3627void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3628{
3629 const VertexAttribCurrentValueData &currentValues =
3630 getGLState().getVertexAttribCurrentValue(index);
3631 const VertexArray *vao = getGLState().getVertexArray();
3632 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3633 currentValues, pname, params);
3634}
3635
3636void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3637{
3638 const VertexAttribCurrentValueData &currentValues =
3639 getGLState().getVertexAttribCurrentValue(index);
3640 const VertexArray *vao = getGLState().getVertexArray();
3641 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3642 currentValues, pname, params);
3643}
3644
3645void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3646{
3647 const VertexAttribCurrentValueData &currentValues =
3648 getGLState().getVertexAttribCurrentValue(index);
3649 const VertexArray *vao = getGLState().getVertexArray();
3650 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3651 currentValues, pname, params);
3652}
3653
3654void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3655{
3656 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3657 QueryVertexAttribPointerv(attrib, pname, pointer);
3658}
3659
Jamie Madillc20ab272016-06-09 07:20:46 -07003660void Context::debugMessageControl(GLenum source,
3661 GLenum type,
3662 GLenum severity,
3663 GLsizei count,
3664 const GLuint *ids,
3665 GLboolean enabled)
3666{
3667 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003668 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3669 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003670}
3671
3672void Context::debugMessageInsert(GLenum source,
3673 GLenum type,
3674 GLuint id,
3675 GLenum severity,
3676 GLsizei length,
3677 const GLchar *buf)
3678{
3679 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003680 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003681}
3682
3683void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3684{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003685 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003686}
3687
3688GLuint Context::getDebugMessageLog(GLuint count,
3689 GLsizei bufSize,
3690 GLenum *sources,
3691 GLenum *types,
3692 GLuint *ids,
3693 GLenum *severities,
3694 GLsizei *lengths,
3695 GLchar *messageLog)
3696{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003697 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3698 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003699}
3700
3701void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3702{
3703 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003704 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003705}
3706
3707void Context::popDebugGroup()
3708{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003709 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003710}
3711
Jamie Madill29639852016-09-02 15:00:09 -04003712void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3713{
3714 Buffer *buffer = mGLState.getTargetBuffer(target);
3715 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003716 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003717}
3718
3719void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3720{
3721 if (data == nullptr)
3722 {
3723 return;
3724 }
3725
3726 Buffer *buffer = mGLState.getTargetBuffer(target);
3727 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003728 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003729}
3730
Jamie Madillef300b12016-10-07 15:12:09 -04003731void Context::attachShader(GLuint program, GLuint shader)
3732{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003733 auto programObject = mState.mShaderPrograms->getProgram(program);
3734 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003735 ASSERT(programObject && shaderObject);
3736 programObject->attachShader(shaderObject);
3737}
3738
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003739const Workarounds &Context::getWorkarounds() const
3740{
3741 return mWorkarounds;
3742}
3743
Jamie Madillb0817d12016-11-01 15:48:31 -04003744void Context::copyBufferSubData(GLenum readTarget,
3745 GLenum writeTarget,
3746 GLintptr readOffset,
3747 GLintptr writeOffset,
3748 GLsizeiptr size)
3749{
3750 // if size is zero, the copy is a successful no-op
3751 if (size == 0)
3752 {
3753 return;
3754 }
3755
3756 // TODO(jmadill): cache these.
3757 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3758 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3759
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003760 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003761}
3762
Jamie Madill01a80ee2016-11-07 12:06:18 -05003763void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3764{
3765 Program *programObject = getProgram(program);
3766 // TODO(jmadill): Re-use this from the validation if possible.
3767 ASSERT(programObject);
3768 programObject->bindAttributeLocation(index, name);
3769}
3770
3771void Context::bindBuffer(GLenum target, GLuint buffer)
3772{
3773 switch (target)
3774 {
3775 case GL_ARRAY_BUFFER:
3776 bindArrayBuffer(buffer);
3777 break;
3778 case GL_ELEMENT_ARRAY_BUFFER:
3779 bindElementArrayBuffer(buffer);
3780 break;
3781 case GL_COPY_READ_BUFFER:
3782 bindCopyReadBuffer(buffer);
3783 break;
3784 case GL_COPY_WRITE_BUFFER:
3785 bindCopyWriteBuffer(buffer);
3786 break;
3787 case GL_PIXEL_PACK_BUFFER:
3788 bindPixelPackBuffer(buffer);
3789 break;
3790 case GL_PIXEL_UNPACK_BUFFER:
3791 bindPixelUnpackBuffer(buffer);
3792 break;
3793 case GL_UNIFORM_BUFFER:
3794 bindGenericUniformBuffer(buffer);
3795 break;
3796 case GL_TRANSFORM_FEEDBACK_BUFFER:
3797 bindGenericTransformFeedbackBuffer(buffer);
3798 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003799 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003800 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003801 break;
3802 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003803 if (buffer != 0)
3804 {
3805 // Binding buffers to this binding point is not implemented yet.
3806 UNIMPLEMENTED();
3807 }
Geoff Lang3b573612016-10-31 14:08:10 -04003808 break;
3809 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003810 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003811 break;
3812 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003813 if (buffer != 0)
3814 {
3815 // Binding buffers to this binding point is not implemented yet.
3816 UNIMPLEMENTED();
3817 }
Geoff Lang3b573612016-10-31 14:08:10 -04003818 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003819
3820 default:
3821 UNREACHABLE();
3822 break;
3823 }
3824}
3825
Jiajia Qin6eafb042016-12-27 17:04:07 +08003826void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3827{
3828 bindBufferRange(target, index, buffer, 0, 0);
3829}
3830
3831void Context::bindBufferRange(GLenum target,
3832 GLuint index,
3833 GLuint buffer,
3834 GLintptr offset,
3835 GLsizeiptr size)
3836{
3837 switch (target)
3838 {
3839 case GL_TRANSFORM_FEEDBACK_BUFFER:
3840 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3841 bindGenericTransformFeedbackBuffer(buffer);
3842 break;
3843 case GL_UNIFORM_BUFFER:
3844 bindIndexedUniformBuffer(buffer, index, offset, size);
3845 bindGenericUniformBuffer(buffer);
3846 break;
3847 case GL_ATOMIC_COUNTER_BUFFER:
3848 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3849 bindGenericAtomicCounterBuffer(buffer);
3850 break;
3851 case GL_SHADER_STORAGE_BUFFER:
3852 if (buffer != 0)
3853 {
3854 // Binding buffers to this binding point is not implemented yet.
3855 UNIMPLEMENTED();
3856 }
3857 break;
3858 default:
3859 UNREACHABLE();
3860 break;
3861 }
3862}
3863
Jamie Madill01a80ee2016-11-07 12:06:18 -05003864void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3865{
3866 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3867 {
3868 bindReadFramebuffer(framebuffer);
3869 }
3870
3871 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3872 {
3873 bindDrawFramebuffer(framebuffer);
3874 }
3875}
3876
3877void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3878{
3879 ASSERT(target == GL_RENDERBUFFER);
3880 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003881 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003882 mGLState.setRenderbufferBinding(object);
3883}
3884
JiangYizhoubddc46b2016-12-09 09:50:51 +08003885void Context::texStorage2DMultisample(GLenum target,
3886 GLsizei samples,
3887 GLenum internalformat,
3888 GLsizei width,
3889 GLsizei height,
3890 GLboolean fixedsamplelocations)
3891{
3892 Extents size(width, height, 1);
3893 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003894 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003895 fixedsamplelocations));
3896}
3897
3898void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3899{
3900 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3901 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3902
3903 switch (pname)
3904 {
3905 case GL_SAMPLE_POSITION:
3906 handleError(framebuffer->getSamplePosition(index, val));
3907 break;
3908 default:
3909 UNREACHABLE();
3910 }
3911}
3912
Jamie Madille8fb6402017-02-14 17:56:40 -05003913void Context::renderbufferStorage(GLenum target,
3914 GLenum internalformat,
3915 GLsizei width,
3916 GLsizei height)
3917{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003918 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3919 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3920
Jamie Madille8fb6402017-02-14 17:56:40 -05003921 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003922 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003923}
3924
3925void Context::renderbufferStorageMultisample(GLenum target,
3926 GLsizei samples,
3927 GLenum internalformat,
3928 GLsizei width,
3929 GLsizei height)
3930{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003931 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3932 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05003933
3934 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003935 handleError(
3936 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003937}
3938
JiangYizhoue18e6392017-02-20 10:32:23 +08003939void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
3940{
3941 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3942 QueryFramebufferParameteriv(framebuffer, pname, params);
3943}
3944
3945void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
3946{
3947 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3948 SetFramebufferParameteri(framebuffer, pname, param);
3949}
3950
Jamie Madille14951e2017-03-09 18:55:16 -05003951Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
3952{
3953 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
3954 {
3955 return gl::OutOfMemory() << "Failed to allocate internal buffer.";
3956 }
3957 return gl::NoError();
3958}
3959
Jamie Madillc29968b2016-01-20 11:17:23 -05003960} // namespace gl