blob: 72ace5e48ecf3a0221a25dc8570cb9579c4e8a74 [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);
Shao80957d92017-02-20 21:25:59 +0800997 mGLState.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
Shao80957d92017-02-20 21:25:59 +08001037void Context::bindVertexBuffer(GLuint bindingIndex,
1038 GLuint bufferHandle,
1039 GLintptr offset,
1040 GLsizei stride)
1041{
1042 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1043 mGLState.bindVertexBuffer(bindingIndex, buffer, offset, stride);
1044}
1045
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001046void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001047{
Geoff Lang76b10c92014-09-05 16:28:14 -04001048 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001049 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001050 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001051 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001052}
1053
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001054void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +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.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1061 GLuint index,
1062 GLintptr offset,
1063 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001064{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001065 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001066 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001067}
1068
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001069void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +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()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001073}
1074
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001075void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1076 GLuint index,
1077 GLintptr offset,
1078 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001079{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001080 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001081 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001082}
1083
Jiajia Qin6eafb042016-12-27 17:04:07 +08001084void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1085{
1086 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1087 mGLState.setGenericAtomicCounterBufferBinding(buffer);
1088}
1089
1090void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1091 GLuint index,
1092 GLintptr offset,
1093 GLsizeiptr size)
1094{
1095 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1096 mGLState.setIndexedAtomicCounterBufferBinding(index, buffer, offset, size);
1097}
1098
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001099void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001100{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001101 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001102 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001103}
1104
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001105void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001106{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001107 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001108 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001109}
1110
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001111void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001112{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001113 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001114 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001115}
1116
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001117void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001118{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001119 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001120 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001121}
1122
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001123void Context::useProgram(GLuint program)
1124{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001125 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001126}
1127
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001128void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001129{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001130 TransformFeedback *transformFeedback =
1131 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001132 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001133}
1134
Geoff Lang5aad9672014-09-08 11:10:42 -04001135Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001136{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001137 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001138 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001139
Geoff Lang5aad9672014-09-08 11:10:42 -04001140 // begin query
1141 Error error = queryObject->begin();
1142 if (error.isError())
1143 {
1144 return error;
1145 }
1146
1147 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001148 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001149
He Yunchaoacd18982017-01-04 10:46:42 +08001150 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001151}
1152
Geoff Lang5aad9672014-09-08 11:10:42 -04001153Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001154{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001155 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001156 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001157
Geoff Lang5aad9672014-09-08 11:10:42 -04001158 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001159
Geoff Lang5aad9672014-09-08 11:10:42 -04001160 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001161 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001162
1163 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001164}
1165
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001166Error Context::queryCounter(GLuint id, GLenum target)
1167{
1168 ASSERT(target == GL_TIMESTAMP_EXT);
1169
1170 Query *queryObject = getQuery(id, true, target);
1171 ASSERT(queryObject);
1172
1173 return queryObject->queryCounter();
1174}
1175
1176void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1177{
1178 switch (pname)
1179 {
1180 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001181 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001182 break;
1183 case GL_QUERY_COUNTER_BITS_EXT:
1184 switch (target)
1185 {
1186 case GL_TIME_ELAPSED_EXT:
1187 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1188 break;
1189 case GL_TIMESTAMP_EXT:
1190 params[0] = getExtensions().queryCounterBitsTimestamp;
1191 break;
1192 default:
1193 UNREACHABLE();
1194 params[0] = 0;
1195 break;
1196 }
1197 break;
1198 default:
1199 UNREACHABLE();
1200 return;
1201 }
1202}
1203
Geoff Lang2186c382016-10-14 10:54:54 -04001204void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001205{
Geoff Lang2186c382016-10-14 10:54:54 -04001206 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001207}
1208
Geoff Lang2186c382016-10-14 10:54:54 -04001209void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001210{
Geoff Lang2186c382016-10-14 10:54:54 -04001211 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001212}
1213
Geoff Lang2186c382016-10-14 10:54:54 -04001214void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001215{
Geoff Lang2186c382016-10-14 10:54:54 -04001216 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001217}
1218
Geoff Lang2186c382016-10-14 10:54:54 -04001219void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001220{
Geoff Lang2186c382016-10-14 10:54:54 -04001221 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001222}
1223
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001224Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001226 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001227}
1228
Jamie Madill33dc8432013-07-26 11:55:05 -04001229FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001230{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001231 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232
Jamie Madill33dc8432013-07-26 11:55:05 -04001233 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001234 {
1235 return NULL;
1236 }
1237 else
1238 {
1239 return fence->second;
1240 }
1241}
1242
1243Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1244{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001245 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246
1247 if (query == mQueryMap.end())
1248 {
1249 return NULL;
1250 }
1251 else
1252 {
1253 if (!query->second && create)
1254 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001255 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001256 query->second->addRef();
1257 }
1258 return query->second;
1259 }
1260}
1261
Geoff Lang70d0f492015-12-10 17:45:46 -05001262Query *Context::getQuery(GLuint handle) const
1263{
1264 auto iter = mQueryMap.find(handle);
1265 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1266}
1267
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001268Texture *Context::getTargetTexture(GLenum target) const
1269{
Ian Ewellbda75592016-04-18 17:25:54 -04001270 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001271 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001272}
1273
Geoff Lang76b10c92014-09-05 16:28:14 -04001274Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001276 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277}
1278
Geoff Lang492a7e42014-11-05 13:27:06 -05001279Compiler *Context::getCompiler() const
1280{
1281 return mCompiler;
1282}
1283
Jamie Madill893ab082014-05-16 16:56:10 -04001284void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001285{
1286 switch (pname)
1287 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001288 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001289 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001290 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001291 mGLState.getBooleanv(pname, params);
1292 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001293 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001294}
1295
Jamie Madill893ab082014-05-16 16:56:10 -04001296void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001297{
Shannon Woods53a94a82014-06-24 15:20:36 -04001298 // Queries about context capabilities and maximums are answered by Context.
1299 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001300 switch (pname)
1301 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001302 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001303 params[0] = mCaps.minAliasedLineWidth;
1304 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001305 break;
1306 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001307 params[0] = mCaps.minAliasedPointSize;
1308 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001309 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001310 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001311 ASSERT(mExtensions.textureFilterAnisotropic);
1312 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001313 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001314 case GL_MAX_TEXTURE_LOD_BIAS:
1315 *params = mCaps.maxLODBias;
1316 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001317
1318 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1319 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1320 {
1321 ASSERT(mExtensions.pathRendering);
1322 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1323 memcpy(params, m, 16 * sizeof(GLfloat));
1324 }
1325 break;
1326
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001327 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001328 mGLState.getFloatv(pname, params);
1329 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001331}
1332
Jamie Madill893ab082014-05-16 16:56:10 -04001333void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001334{
Shannon Woods53a94a82014-06-24 15:20:36 -04001335 // Queries about context capabilities and maximums are answered by Context.
1336 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001337
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001338 switch (pname)
1339 {
Geoff Lang301d1612014-07-09 10:34:37 -04001340 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1341 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1342 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001343 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1344 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1345 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001346 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1347 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1348 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001349 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001350 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1351 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1352 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001353 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001354 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001355 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1356 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1357 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1358 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001359 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1360 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001361 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1362 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001363 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001364 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1365 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1366 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1367 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001368 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001369 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001370 break;
1371 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001372 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001373 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001374 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1375 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001376 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1377 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1378 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001379 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1380 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1381 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001382 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001383 case GL_MAX_VIEWPORT_DIMS:
1384 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001385 params[0] = mCaps.maxViewportWidth;
1386 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001387 }
1388 break;
1389 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001390 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001391 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001392 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1393 *params = mResetStrategy;
1394 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001395 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001396 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001397 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001398 case GL_SHADER_BINARY_FORMATS:
1399 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1400 break;
1401 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001402 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001403 break;
1404 case GL_PROGRAM_BINARY_FORMATS:
1405 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001406 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001407 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001408 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001409 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001410
1411 // GL_KHR_debug
1412 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1413 *params = mExtensions.maxDebugMessageLength;
1414 break;
1415 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1416 *params = mExtensions.maxDebugLoggedMessages;
1417 break;
1418 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1419 *params = mExtensions.maxDebugGroupStackDepth;
1420 break;
1421 case GL_MAX_LABEL_LENGTH:
1422 *params = mExtensions.maxLabelLength;
1423 break;
1424
Ian Ewell53f59f42016-01-28 17:36:55 -05001425 // GL_EXT_disjoint_timer_query
1426 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001427 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001428 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001429 case GL_MAX_FRAMEBUFFER_WIDTH:
1430 *params = mCaps.maxFramebufferWidth;
1431 break;
1432 case GL_MAX_FRAMEBUFFER_HEIGHT:
1433 *params = mCaps.maxFramebufferHeight;
1434 break;
1435 case GL_MAX_FRAMEBUFFER_SAMPLES:
1436 *params = mCaps.maxFramebufferSamples;
1437 break;
1438 case GL_MAX_SAMPLE_MASK_WORDS:
1439 *params = mCaps.maxSampleMaskWords;
1440 break;
1441 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1442 *params = mCaps.maxColorTextureSamples;
1443 break;
1444 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1445 *params = mCaps.maxDepthTextureSamples;
1446 break;
1447 case GL_MAX_INTEGER_SAMPLES:
1448 *params = mCaps.maxIntegerSamples;
1449 break;
1450 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1451 *params = mCaps.maxVertexAttribRelativeOffset;
1452 break;
1453 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1454 *params = mCaps.maxVertexAttribBindings;
1455 break;
1456 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1457 *params = mCaps.maxVertexAttribStride;
1458 break;
1459 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1460 *params = mCaps.maxVertexAtomicCounterBuffers;
1461 break;
1462 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1463 *params = mCaps.maxVertexAtomicCounters;
1464 break;
1465 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1466 *params = mCaps.maxVertexImageUniforms;
1467 break;
1468 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1469 *params = mCaps.maxVertexShaderStorageBlocks;
1470 break;
1471 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1472 *params = mCaps.maxFragmentAtomicCounterBuffers;
1473 break;
1474 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1475 *params = mCaps.maxFragmentAtomicCounters;
1476 break;
1477 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1478 *params = mCaps.maxFragmentImageUniforms;
1479 break;
1480 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1481 *params = mCaps.maxFragmentShaderStorageBlocks;
1482 break;
1483 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1484 *params = mCaps.minProgramTextureGatherOffset;
1485 break;
1486 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1487 *params = mCaps.maxProgramTextureGatherOffset;
1488 break;
1489 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1490 *params = mCaps.maxComputeWorkGroupInvocations;
1491 break;
1492 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1493 *params = mCaps.maxComputeUniformBlocks;
1494 break;
1495 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1496 *params = mCaps.maxComputeTextureImageUnits;
1497 break;
1498 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1499 *params = mCaps.maxComputeSharedMemorySize;
1500 break;
1501 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1502 *params = mCaps.maxComputeUniformComponents;
1503 break;
1504 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1505 *params = mCaps.maxComputeAtomicCounterBuffers;
1506 break;
1507 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1508 *params = mCaps.maxComputeAtomicCounters;
1509 break;
1510 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1511 *params = mCaps.maxComputeImageUniforms;
1512 break;
1513 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1514 *params = mCaps.maxCombinedComputeUniformComponents;
1515 break;
1516 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1517 *params = mCaps.maxComputeShaderStorageBlocks;
1518 break;
1519 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1520 *params = mCaps.maxCombinedShaderOutputResources;
1521 break;
1522 case GL_MAX_UNIFORM_LOCATIONS:
1523 *params = mCaps.maxUniformLocations;
1524 break;
1525 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1526 *params = mCaps.maxAtomicCounterBufferBindings;
1527 break;
1528 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1529 *params = mCaps.maxAtomicCounterBufferSize;
1530 break;
1531 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1532 *params = mCaps.maxCombinedAtomicCounterBuffers;
1533 break;
1534 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1535 *params = mCaps.maxCombinedAtomicCounters;
1536 break;
1537 case GL_MAX_IMAGE_UNITS:
1538 *params = mCaps.maxImageUnits;
1539 break;
1540 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1541 *params = mCaps.maxCombinedImageUniforms;
1542 break;
1543 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1544 *params = mCaps.maxShaderStorageBufferBindings;
1545 break;
1546 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1547 *params = mCaps.maxCombinedShaderStorageBlocks;
1548 break;
1549 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1550 *params = mCaps.shaderStorageBufferOffsetAlignment;
1551 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001552 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001553 mGLState.getIntegerv(mState, pname, params);
1554 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001555 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001556}
1557
Jamie Madill893ab082014-05-16 16:56:10 -04001558void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001559{
Shannon Woods53a94a82014-06-24 15:20:36 -04001560 // Queries about context capabilities and maximums are answered by Context.
1561 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001562 switch (pname)
1563 {
1564 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001565 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001566 break;
1567 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001568 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001569 break;
1570 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001571 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001572 break;
1573 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001574 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001575 break;
1576 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001577 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001578 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001579
1580 // GL_EXT_disjoint_timer_query
1581 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001582 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001583 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001584
1585 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1586 *params = mCaps.maxShaderStorageBlockSize;
1587 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001588 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001589 UNREACHABLE();
1590 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001591 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001592}
1593
Geoff Lang70d0f492015-12-10 17:45:46 -05001594void Context::getPointerv(GLenum pname, void **params) const
1595{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001596 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001597}
1598
Martin Radev66fb8202016-07-28 11:45:20 +03001599void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001600{
Shannon Woods53a94a82014-06-24 15:20:36 -04001601 // Queries about context capabilities and maximums are answered by Context.
1602 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001603
1604 GLenum nativeType;
1605 unsigned int numParams;
1606 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1607 ASSERT(queryStatus);
1608
1609 if (nativeType == GL_INT)
1610 {
1611 switch (target)
1612 {
1613 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1614 ASSERT(index < 3u);
1615 *data = mCaps.maxComputeWorkGroupCount[index];
1616 break;
1617 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1618 ASSERT(index < 3u);
1619 *data = mCaps.maxComputeWorkGroupSize[index];
1620 break;
1621 default:
1622 mGLState.getIntegeri_v(target, index, data);
1623 }
1624 }
1625 else
1626 {
1627 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1628 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001629}
1630
Martin Radev66fb8202016-07-28 11:45:20 +03001631void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001632{
Shannon Woods53a94a82014-06-24 15:20:36 -04001633 // Queries about context capabilities and maximums are answered by Context.
1634 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001635
1636 GLenum nativeType;
1637 unsigned int numParams;
1638 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1639 ASSERT(queryStatus);
1640
1641 if (nativeType == GL_INT_64_ANGLEX)
1642 {
1643 mGLState.getInteger64i_v(target, index, data);
1644 }
1645 else
1646 {
1647 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1648 }
1649}
1650
1651void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1652{
1653 // Queries about context capabilities and maximums are answered by Context.
1654 // Queries about current GL state values are answered by State.
1655
1656 GLenum nativeType;
1657 unsigned int numParams;
1658 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1659 ASSERT(queryStatus);
1660
1661 if (nativeType == GL_BOOL)
1662 {
1663 mGLState.getBooleani_v(target, index, data);
1664 }
1665 else
1666 {
1667 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1668 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001669}
1670
He Yunchao010e4db2017-03-03 14:22:06 +08001671void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1672{
1673 Buffer *buffer = mGLState.getTargetBuffer(target);
1674 QueryBufferParameteriv(buffer, pname, params);
1675}
1676
1677void Context::getFramebufferAttachmentParameteriv(GLenum target,
1678 GLenum attachment,
1679 GLenum pname,
1680 GLint *params)
1681{
1682 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1683 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1684}
1685
1686void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1687{
1688 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1689 QueryRenderbufferiv(this, renderbuffer, pname, params);
1690}
1691
1692void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1693{
1694 Texture *texture = getTargetTexture(target);
1695 QueryTexParameterfv(texture, pname, params);
1696}
1697
1698void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1699{
1700 Texture *texture = getTargetTexture(target);
1701 QueryTexParameteriv(texture, pname, params);
1702}
1703void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1704{
1705 Texture *texture = getTargetTexture(target);
1706 SetTexParameterf(texture, pname, param);
1707}
1708
1709void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1710{
1711 Texture *texture = getTargetTexture(target);
1712 SetTexParameterfv(texture, pname, params);
1713}
1714
1715void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1716{
1717 Texture *texture = getTargetTexture(target);
1718 SetTexParameteri(texture, pname, param);
1719}
1720
1721void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1722{
1723 Texture *texture = getTargetTexture(target);
1724 SetTexParameteriv(texture, pname, params);
1725}
1726
Jamie Madill675fe712016-12-19 13:07:54 -05001727void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001728{
Jamie Madill1b94d432015-08-07 13:23:23 -04001729 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001730 auto error = mImplementation->drawArrays(mode, first, count);
1731 handleError(error);
1732 if (!error.isError())
1733 {
1734 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1735 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001736}
1737
Jamie Madill675fe712016-12-19 13:07:54 -05001738void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001739{
1740 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001741 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1742 handleError(error);
1743 if (!error.isError())
1744 {
1745 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1746 }
Geoff Langf6db0982015-08-25 13:04:00 -04001747}
1748
Jamie Madill675fe712016-12-19 13:07:54 -05001749void Context::drawElements(GLenum mode,
1750 GLsizei count,
1751 GLenum type,
1752 const GLvoid *indices,
1753 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001754{
Jamie Madill1b94d432015-08-07 13:23:23 -04001755 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001756 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001757}
1758
Jamie Madill675fe712016-12-19 13:07:54 -05001759void Context::drawElementsInstanced(GLenum mode,
1760 GLsizei count,
1761 GLenum type,
1762 const GLvoid *indices,
1763 GLsizei instances,
1764 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001765{
1766 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001767 handleError(
1768 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001769}
1770
Jamie Madill675fe712016-12-19 13:07:54 -05001771void Context::drawRangeElements(GLenum mode,
1772 GLuint start,
1773 GLuint end,
1774 GLsizei count,
1775 GLenum type,
1776 const GLvoid *indices,
1777 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001778{
1779 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001780 handleError(
1781 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001782}
1783
Jiajia Qind9671222016-11-29 16:30:31 +08001784void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1785{
1786 syncRendererState();
1787 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1788}
1789
1790void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1791{
1792 syncRendererState();
1793 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1794}
1795
Jamie Madill675fe712016-12-19 13:07:54 -05001796void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001797{
Jamie Madill675fe712016-12-19 13:07:54 -05001798 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001799}
1800
Jamie Madill675fe712016-12-19 13:07:54 -05001801void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001802{
Jamie Madill675fe712016-12-19 13:07:54 -05001803 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001804}
1805
Austin Kinross6ee1e782015-05-29 17:05:37 -07001806void Context::insertEventMarker(GLsizei length, const char *marker)
1807{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001808 ASSERT(mImplementation);
1809 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001810}
1811
1812void Context::pushGroupMarker(GLsizei length, const char *marker)
1813{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001814 ASSERT(mImplementation);
1815 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001816}
1817
1818void Context::popGroupMarker()
1819{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001820 ASSERT(mImplementation);
1821 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001822}
1823
Geoff Langd8605522016-04-13 10:19:12 -04001824void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1825{
1826 Program *programObject = getProgram(program);
1827 ASSERT(programObject);
1828
1829 programObject->bindUniformLocation(location, name);
1830}
1831
Sami Väisänena797e062016-05-12 15:23:40 +03001832void Context::setCoverageModulation(GLenum components)
1833{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001834 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001835}
1836
Sami Väisänene45e53b2016-05-25 10:36:04 +03001837void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1838{
1839 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1840}
1841
1842void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1843{
1844 GLfloat I[16];
1845 angle::Matrix<GLfloat>::setToIdentity(I);
1846
1847 mGLState.loadPathRenderingMatrix(matrixMode, I);
1848}
1849
1850void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1851{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001852 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001853 if (!pathObj)
1854 return;
1855
1856 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1857 syncRendererState();
1858
1859 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1860}
1861
1862void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1863{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001864 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001865 if (!pathObj)
1866 return;
1867
1868 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1869 syncRendererState();
1870
1871 mImplementation->stencilStrokePath(pathObj, reference, mask);
1872}
1873
1874void Context::coverFillPath(GLuint path, GLenum coverMode)
1875{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001876 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001877 if (!pathObj)
1878 return;
1879
1880 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1881 syncRendererState();
1882
1883 mImplementation->coverFillPath(pathObj, coverMode);
1884}
1885
1886void Context::coverStrokePath(GLuint path, GLenum coverMode)
1887{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001888 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001889 if (!pathObj)
1890 return;
1891
1892 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1893 syncRendererState();
1894
1895 mImplementation->coverStrokePath(pathObj, coverMode);
1896}
1897
1898void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1899{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001900 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001901 if (!pathObj)
1902 return;
1903
1904 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1905 syncRendererState();
1906
1907 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1908}
1909
1910void Context::stencilThenCoverStrokePath(GLuint path,
1911 GLint reference,
1912 GLuint mask,
1913 GLenum coverMode)
1914{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001915 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001916 if (!pathObj)
1917 return;
1918
1919 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1920 syncRendererState();
1921
1922 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1923}
1924
Sami Väisänend59ca052016-06-21 16:10:00 +03001925void Context::coverFillPathInstanced(GLsizei numPaths,
1926 GLenum pathNameType,
1927 const void *paths,
1928 GLuint pathBase,
1929 GLenum coverMode,
1930 GLenum transformType,
1931 const GLfloat *transformValues)
1932{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001933 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001934
1935 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1936 syncRendererState();
1937
1938 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1939}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001940
Sami Väisänend59ca052016-06-21 16:10:00 +03001941void Context::coverStrokePathInstanced(GLsizei numPaths,
1942 GLenum pathNameType,
1943 const void *paths,
1944 GLuint pathBase,
1945 GLenum coverMode,
1946 GLenum transformType,
1947 const GLfloat *transformValues)
1948{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001949 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001950
1951 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1952 syncRendererState();
1953
1954 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1955 transformValues);
1956}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001957
Sami Väisänend59ca052016-06-21 16:10:00 +03001958void Context::stencilFillPathInstanced(GLsizei numPaths,
1959 GLenum pathNameType,
1960 const void *paths,
1961 GLuint pathBase,
1962 GLenum fillMode,
1963 GLuint mask,
1964 GLenum transformType,
1965 const GLfloat *transformValues)
1966{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001967 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001968
1969 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1970 syncRendererState();
1971
1972 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1973 transformValues);
1974}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001975
Sami Väisänend59ca052016-06-21 16:10:00 +03001976void Context::stencilStrokePathInstanced(GLsizei numPaths,
1977 GLenum pathNameType,
1978 const void *paths,
1979 GLuint pathBase,
1980 GLint reference,
1981 GLuint mask,
1982 GLenum transformType,
1983 const GLfloat *transformValues)
1984{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001985 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001986
1987 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1988 syncRendererState();
1989
1990 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1991 transformValues);
1992}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001993
Sami Väisänend59ca052016-06-21 16:10:00 +03001994void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1995 GLenum pathNameType,
1996 const void *paths,
1997 GLuint pathBase,
1998 GLenum fillMode,
1999 GLuint mask,
2000 GLenum coverMode,
2001 GLenum transformType,
2002 const GLfloat *transformValues)
2003{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002004 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002005
2006 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2007 syncRendererState();
2008
2009 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2010 transformType, transformValues);
2011}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002012
Sami Väisänend59ca052016-06-21 16:10:00 +03002013void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2014 GLenum pathNameType,
2015 const void *paths,
2016 GLuint pathBase,
2017 GLint reference,
2018 GLuint mask,
2019 GLenum coverMode,
2020 GLenum transformType,
2021 const GLfloat *transformValues)
2022{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002023 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002024
2025 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2026 syncRendererState();
2027
2028 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2029 transformType, transformValues);
2030}
2031
Sami Väisänen46eaa942016-06-29 10:26:37 +03002032void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2033{
2034 auto *programObject = getProgram(program);
2035
2036 programObject->bindFragmentInputLocation(location, name);
2037}
2038
2039void Context::programPathFragmentInputGen(GLuint program,
2040 GLint location,
2041 GLenum genMode,
2042 GLint components,
2043 const GLfloat *coeffs)
2044{
2045 auto *programObject = getProgram(program);
2046
2047 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
2048}
2049
jchen1015015f72017-03-16 13:54:21 +08002050GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2051{
jchen10fd7c3b52017-03-21 15:36:03 +08002052 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002053 return QueryProgramResourceIndex(programObject, programInterface, name);
2054}
2055
jchen10fd7c3b52017-03-21 15:36:03 +08002056void Context::getProgramResourceName(GLuint program,
2057 GLenum programInterface,
2058 GLuint index,
2059 GLsizei bufSize,
2060 GLsizei *length,
2061 GLchar *name)
2062{
2063 const auto *programObject = getProgram(program);
2064 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2065}
2066
Jamie Madill437fa652016-05-03 15:13:24 -04002067void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002068{
Geoff Langda5777c2014-07-11 09:52:58 -04002069 if (error.isError())
2070 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002071 GLenum code = error.getCode();
2072 mErrors.insert(code);
2073 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2074 {
2075 markContextLost();
2076 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002077
2078 if (!error.getMessage().empty())
2079 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002080 auto *debug = &mGLState.getDebug();
2081 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2082 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002083 }
Geoff Langda5777c2014-07-11 09:52:58 -04002084 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002085}
2086
2087// Get one of the recorded errors and clear its flag, if any.
2088// [OpenGL ES 2.0.24] section 2.5 page 13.
2089GLenum Context::getError()
2090{
Geoff Langda5777c2014-07-11 09:52:58 -04002091 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002092 {
Geoff Langda5777c2014-07-11 09:52:58 -04002093 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002094 }
Geoff Langda5777c2014-07-11 09:52:58 -04002095 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002096 {
Geoff Langda5777c2014-07-11 09:52:58 -04002097 GLenum error = *mErrors.begin();
2098 mErrors.erase(mErrors.begin());
2099 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002100 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002101}
2102
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002103// NOTE: this function should not assume that this context is current!
2104void Context::markContextLost()
2105{
2106 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002107 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002108 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002109 mContextLostForced = true;
2110 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002111 mContextLost = true;
2112}
2113
2114bool Context::isContextLost()
2115{
2116 return mContextLost;
2117}
2118
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002119GLenum Context::getResetStatus()
2120{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002121 // Even if the application doesn't want to know about resets, we want to know
2122 // as it will allow us to skip all the calls.
2123 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002124 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002125 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002126 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002127 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002128 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002129
2130 // EXT_robustness, section 2.6: If the reset notification behavior is
2131 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2132 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2133 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002134 }
2135
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002136 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2137 // status should be returned at least once, and GL_NO_ERROR should be returned
2138 // once the device has finished resetting.
2139 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002140 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002141 ASSERT(mResetStatus == GL_NO_ERROR);
2142 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002143
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002144 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002145 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002146 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002147 }
2148 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002149 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002150 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002151 // If markContextLost was used to mark the context lost then
2152 // assume that is not recoverable, and continue to report the
2153 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002154 mResetStatus = mImplementation->getResetStatus();
2155 }
Jamie Madill893ab082014-05-16 16:56:10 -04002156
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002157 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002158}
2159
2160bool Context::isResetNotificationEnabled()
2161{
2162 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2163}
2164
Corentin Walleze3b10e82015-05-20 11:06:25 -04002165const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002166{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002167 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002168}
2169
2170EGLenum Context::getClientType() const
2171{
2172 return mClientType;
2173}
2174
2175EGLenum Context::getRenderBuffer() const
2176{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002177 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2178 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002179 {
2180 return EGL_NONE;
2181 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002182
2183 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2184 ASSERT(backAttachment != nullptr);
2185 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002186}
2187
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002188VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002189{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002190 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002191 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2192 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002193 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002194 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2195 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002196
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002197 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002198 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002199
2200 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002201}
2202
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002203TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002204{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002205 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002206 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2207 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002208 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002209 transformFeedback =
2210 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002211 transformFeedback->addRef();
2212 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002213 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002214
2215 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002216}
2217
2218bool Context::isVertexArrayGenerated(GLuint vertexArray)
2219{
Geoff Langf41a7152016-09-19 15:11:17 -04002220 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002221 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2222}
2223
2224bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2225{
Geoff Langf41a7152016-09-19 15:11:17 -04002226 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002227 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2228}
2229
Shannon Woods53a94a82014-06-24 15:20:36 -04002230void Context::detachTexture(GLuint texture)
2231{
2232 // Simple pass-through to State's detachTexture method, as textures do not require
2233 // allocation map management either here or in the resource manager at detach time.
2234 // Zero textures are held by the Context, and we don't attempt to request them from
2235 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002236 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002237}
2238
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002239void Context::detachBuffer(GLuint buffer)
2240{
Yuly Novikov5807a532015-12-03 13:01:22 -05002241 // Simple pass-through to State's detachBuffer method, since
2242 // only buffer attachments to container objects that are bound to the current context
2243 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002244
Yuly Novikov5807a532015-12-03 13:01:22 -05002245 // [OpenGL ES 3.2] section 5.1.2 page 45:
2246 // Attachments to unbound container objects, such as
2247 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2248 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002249 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002250}
2251
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002252void Context::detachFramebuffer(GLuint framebuffer)
2253{
Shannon Woods53a94a82014-06-24 15:20:36 -04002254 // Framebuffer detachment is handled by Context, because 0 is a valid
2255 // Framebuffer object, and a pointer to it must be passed from Context
2256 // to State at binding time.
2257
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002258 // [OpenGL ES 2.0.24] section 4.4 page 107:
2259 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2260 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2261
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002262 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002263 {
2264 bindReadFramebuffer(0);
2265 }
2266
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002267 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002268 {
2269 bindDrawFramebuffer(0);
2270 }
2271}
2272
2273void Context::detachRenderbuffer(GLuint renderbuffer)
2274{
Jamie Madilla02315b2017-02-23 14:14:47 -05002275 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002276}
2277
Jamie Madill57a89722013-07-02 11:57:03 -04002278void Context::detachVertexArray(GLuint vertexArray)
2279{
Jamie Madill77a72f62015-04-14 11:18:32 -04002280 // Vertex array detachment is handled by Context, because 0 is a valid
2281 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002282 // binding time.
2283
Jamie Madill57a89722013-07-02 11:57:03 -04002284 // [OpenGL ES 3.0.2] section 2.10 page 43:
2285 // If a vertex array object that is currently bound is deleted, the binding
2286 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002287 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002288 {
2289 bindVertexArray(0);
2290 }
2291}
2292
Geoff Langc8058452014-02-03 12:04:11 -05002293void Context::detachTransformFeedback(GLuint transformFeedback)
2294{
Corentin Walleza2257da2016-04-19 16:43:12 -04002295 // Transform feedback detachment is handled by Context, because 0 is a valid
2296 // transform feedback, and a pointer to it must be passed from Context to State at
2297 // binding time.
2298
2299 // The OpenGL specification doesn't mention what should happen when the currently bound
2300 // transform feedback object is deleted. Since it is a container object, we treat it like
2301 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002302 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002303 {
2304 bindTransformFeedback(0);
2305 }
Geoff Langc8058452014-02-03 12:04:11 -05002306}
2307
Jamie Madilldc356042013-07-19 16:36:57 -04002308void Context::detachSampler(GLuint sampler)
2309{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002310 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002311}
2312
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002313void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2314{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002315 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002316}
2317
Jamie Madille29d1672013-07-19 16:36:57 -04002318void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2319{
Geoff Langc1984ed2016-10-07 12:41:00 -04002320 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002321 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002322 SetSamplerParameteri(samplerObject, pname, param);
2323}
Jamie Madille29d1672013-07-19 16:36:57 -04002324
Geoff Langc1984ed2016-10-07 12:41:00 -04002325void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2326{
2327 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002328 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002329 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002330}
2331
2332void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2333{
Geoff Langc1984ed2016-10-07 12:41:00 -04002334 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002335 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002336 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002337}
2338
Geoff Langc1984ed2016-10-07 12:41:00 -04002339void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002340{
Geoff Langc1984ed2016-10-07 12:41:00 -04002341 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002342 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002343 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002344}
2345
Geoff Langc1984ed2016-10-07 12:41:00 -04002346void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002347{
Geoff Langc1984ed2016-10-07 12:41:00 -04002348 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002349 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002350 QuerySamplerParameteriv(samplerObject, pname, params);
2351}
Jamie Madill9675b802013-07-19 16:36:59 -04002352
Geoff Langc1984ed2016-10-07 12:41:00 -04002353void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2354{
2355 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002356 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002357 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002358}
2359
Olli Etuahof0fee072016-03-30 15:11:58 +03002360void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2361{
2362 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002363 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002364}
2365
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002366void Context::initRendererString()
2367{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002368 std::ostringstream rendererString;
2369 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002370 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002371 rendererString << ")";
2372
Geoff Langcec35902014-04-16 10:52:36 -04002373 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002374}
2375
Geoff Langc339c4e2016-11-29 10:37:36 -05002376void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002377{
Geoff Langc339c4e2016-11-29 10:37:36 -05002378 const Version &clientVersion = getClientVersion();
2379
2380 std::ostringstream versionString;
2381 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2382 << ANGLE_VERSION_STRING << ")";
2383 mVersionString = MakeStaticString(versionString.str());
2384
2385 std::ostringstream shadingLanguageVersionString;
2386 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2387 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2388 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2389 << ")";
2390 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002391}
2392
Geoff Langcec35902014-04-16 10:52:36 -04002393void Context::initExtensionStrings()
2394{
Geoff Langc339c4e2016-11-29 10:37:36 -05002395 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2396 std::ostringstream combinedStringStream;
2397 std::copy(strings.begin(), strings.end(),
2398 std::ostream_iterator<const char *>(combinedStringStream, " "));
2399 return MakeStaticString(combinedStringStream.str());
2400 };
2401
2402 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002403 for (const auto &extensionString : mExtensions.getStrings())
2404 {
2405 mExtensionStrings.push_back(MakeStaticString(extensionString));
2406 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002407 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002408
Bryan Bernhart58806562017-01-05 13:09:31 -08002409 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2410
Geoff Langc339c4e2016-11-29 10:37:36 -05002411 mRequestableExtensionStrings.clear();
2412 for (const auto &extensionInfo : GetExtensionInfoMap())
2413 {
2414 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002415 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2416 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002417 {
2418 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2419 }
2420 }
2421 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002422}
2423
Geoff Langc339c4e2016-11-29 10:37:36 -05002424const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002425{
Geoff Langc339c4e2016-11-29 10:37:36 -05002426 switch (name)
2427 {
2428 case GL_VENDOR:
2429 return reinterpret_cast<const GLubyte *>("Google Inc.");
2430
2431 case GL_RENDERER:
2432 return reinterpret_cast<const GLubyte *>(mRendererString);
2433
2434 case GL_VERSION:
2435 return reinterpret_cast<const GLubyte *>(mVersionString);
2436
2437 case GL_SHADING_LANGUAGE_VERSION:
2438 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2439
2440 case GL_EXTENSIONS:
2441 return reinterpret_cast<const GLubyte *>(mExtensionString);
2442
2443 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2444 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2445
2446 default:
2447 UNREACHABLE();
2448 return nullptr;
2449 }
Geoff Langcec35902014-04-16 10:52:36 -04002450}
2451
Geoff Langc339c4e2016-11-29 10:37:36 -05002452const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002453{
Geoff Langc339c4e2016-11-29 10:37:36 -05002454 switch (name)
2455 {
2456 case GL_EXTENSIONS:
2457 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2458
2459 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2460 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2461
2462 default:
2463 UNREACHABLE();
2464 return nullptr;
2465 }
Geoff Langcec35902014-04-16 10:52:36 -04002466}
2467
2468size_t Context::getExtensionStringCount() const
2469{
2470 return mExtensionStrings.size();
2471}
2472
Geoff Langc339c4e2016-11-29 10:37:36 -05002473void Context::requestExtension(const char *name)
2474{
2475 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2476 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2477 const auto &extension = extensionInfos.at(name);
2478 ASSERT(extension.Requestable);
2479
2480 if (mExtensions.*(extension.ExtensionsMember))
2481 {
2482 // Extension already enabled
2483 return;
2484 }
2485
2486 mExtensions.*(extension.ExtensionsMember) = true;
2487 updateCaps();
2488 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002489
2490 // Re-create the compiler with the requested extensions enabled.
2491 SafeDelete(mCompiler);
2492 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002493}
2494
2495size_t Context::getRequestableExtensionStringCount() const
2496{
2497 return mRequestableExtensionStrings.size();
2498}
2499
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002500void Context::beginTransformFeedback(GLenum primitiveMode)
2501{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002502 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002503 ASSERT(transformFeedback != nullptr);
2504 ASSERT(!transformFeedback->isPaused());
2505
Jamie Madill6c1f6712017-02-14 19:08:04 -05002506 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002507}
2508
2509bool Context::hasActiveTransformFeedback(GLuint program) const
2510{
2511 for (auto pair : mTransformFeedbackMap)
2512 {
2513 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2514 {
2515 return true;
2516 }
2517 }
2518 return false;
2519}
2520
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002521void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002522{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002523 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002524
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002525 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002526
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002527 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002528
Geoff Langeb66a6e2016-10-31 13:06:12 -04002529 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002530 {
2531 // Disable ES3+ extensions
2532 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002533 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002534 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002535 }
2536
Geoff Langeb66a6e2016-10-31 13:06:12 -04002537 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002538 {
2539 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2540 //mExtensions.sRGB = false;
2541 }
2542
Jamie Madill00ed7a12016-05-19 13:13:38 -04002543 // Some extensions are always available because they are implemented in the GL layer.
2544 mExtensions.bindUniformLocation = true;
2545 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002546 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002547 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002548 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002549
2550 // Enable the no error extension if the context was created with the flag.
2551 mExtensions.noError = mSkipValidation;
2552
Corentin Wallezccab69d2017-01-27 16:57:15 -05002553 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002554 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002555
Geoff Lang70d0f492015-12-10 17:45:46 -05002556 // Explicitly enable GL_KHR_debug
2557 mExtensions.debug = true;
2558 mExtensions.maxDebugMessageLength = 1024;
2559 mExtensions.maxDebugLoggedMessages = 1024;
2560 mExtensions.maxDebugGroupStackDepth = 1024;
2561 mExtensions.maxLabelLength = 1024;
2562
Geoff Langff5b2d52016-09-07 11:32:23 -04002563 // Explicitly enable GL_ANGLE_robust_client_memory
2564 mExtensions.robustClientMemory = true;
2565
Jamie Madille08a1d32017-03-07 17:24:06 -05002566 // Determine robust resource init availability from EGL.
2567 mExtensions.robustResourceInitialization =
2568 displayExtensions.createContextRobustResourceInitialization;
2569
Geoff Lang301d1612014-07-09 10:34:37 -04002570 // Apply implementation limits
2571 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002572 mCaps.maxVertexAttribBindings =
2573 getClientVersion() < ES_3_1
2574 ? mCaps.maxVertexAttributes
2575 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2576
Geoff Lang301d1612014-07-09 10:34:37 -04002577 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2578 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2579
2580 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002581
Geoff Langc287ea62016-09-16 14:46:51 -04002582 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002583 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002584 for (const auto &extensionInfo : GetExtensionInfoMap())
2585 {
2586 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002587 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002588 {
2589 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2590 }
2591 }
2592
2593 // Generate texture caps
2594 updateCaps();
2595}
2596
2597void Context::updateCaps()
2598{
Geoff Lang900013c2014-07-07 11:32:19 -04002599 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002600 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002601
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002602 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002603 {
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002604 GLenum format = capsIt.first;
2605 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002606
Geoff Lang5d601382014-07-22 15:14:06 -04002607 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002608
Geoff Lang0d8b7242015-09-09 14:56:53 -04002609 // Update the format caps based on the client version and extensions.
2610 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2611 // ES3.
2612 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002613 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002614 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002615 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002616 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002617 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002618
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002619 // OpenGL ES does not support multisampling with non-rendererable formats
2620 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2621 if (!formatInfo.renderSupport ||
2622 (getClientVersion() < ES_3_1 &&
2623 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002624 {
Geoff Langd87878e2014-09-19 15:42:59 -04002625 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002626 }
Geoff Langd87878e2014-09-19 15:42:59 -04002627
2628 if (formatCaps.texturable && formatInfo.compressed)
2629 {
2630 mCaps.compressedTextureFormats.push_back(format);
2631 }
2632
2633 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002634 }
2635}
2636
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002637void Context::initWorkarounds()
2638{
2639 // Lose the context upon out of memory error if the application is
2640 // expecting to watch for those events.
2641 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2642}
2643
Jamie Madill1b94d432015-08-07 13:23:23 -04002644void Context::syncRendererState()
2645{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002646 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002647 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002648 mGLState.clearDirtyBits();
2649 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002650}
2651
Jamie Madillad9f24e2016-02-12 09:27:24 -05002652void Context::syncRendererState(const State::DirtyBits &bitMask,
2653 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002654{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002655 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002656 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002657 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002658
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002659 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002660}
Jamie Madillc29968b2016-01-20 11:17:23 -05002661
2662void Context::blitFramebuffer(GLint srcX0,
2663 GLint srcY0,
2664 GLint srcX1,
2665 GLint srcY1,
2666 GLint dstX0,
2667 GLint dstY0,
2668 GLint dstX1,
2669 GLint dstY1,
2670 GLbitfield mask,
2671 GLenum filter)
2672{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002673 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002674 ASSERT(drawFramebuffer);
2675
2676 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2677 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2678
Jamie Madillad9f24e2016-02-12 09:27:24 -05002679 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002680
Jamie Madill8415b5f2016-04-26 13:41:39 -04002681 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002682}
Jamie Madillc29968b2016-01-20 11:17:23 -05002683
2684void Context::clear(GLbitfield mask)
2685{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002686 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002687 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002688}
2689
2690void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2691{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002692 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002693 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2694 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002695}
2696
2697void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2698{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002699 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002700 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2701 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002702}
2703
2704void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2705{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002706 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002707 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2708 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002709}
2710
2711void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2712{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002713 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002714 ASSERT(framebufferObject);
2715
2716 // If a buffer is not present, the clear has no effect
2717 if (framebufferObject->getDepthbuffer() == nullptr &&
2718 framebufferObject->getStencilbuffer() == nullptr)
2719 {
2720 return;
2721 }
2722
Jamie Madillad9f24e2016-02-12 09:27:24 -05002723 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002724 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2725 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002726}
2727
2728void Context::readPixels(GLint x,
2729 GLint y,
2730 GLsizei width,
2731 GLsizei height,
2732 GLenum format,
2733 GLenum type,
2734 GLvoid *pixels)
2735{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002736 if (width == 0 || height == 0)
2737 {
2738 return;
2739 }
2740
Jamie Madillad9f24e2016-02-12 09:27:24 -05002741 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002742
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002743 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002744 ASSERT(framebufferObject);
2745
2746 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002747 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002748}
2749
2750void Context::copyTexImage2D(GLenum target,
2751 GLint level,
2752 GLenum internalformat,
2753 GLint x,
2754 GLint y,
2755 GLsizei width,
2756 GLsizei height,
2757 GLint border)
2758{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002759 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002760 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002761
Jamie Madillc29968b2016-01-20 11:17:23 -05002762 Rectangle sourceArea(x, y, width, height);
2763
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002764 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002765 Texture *texture =
2766 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002767 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002768}
2769
2770void Context::copyTexSubImage2D(GLenum target,
2771 GLint level,
2772 GLint xoffset,
2773 GLint yoffset,
2774 GLint x,
2775 GLint y,
2776 GLsizei width,
2777 GLsizei height)
2778{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002779 if (width == 0 || height == 0)
2780 {
2781 return;
2782 }
2783
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002784 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002785 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002786
Jamie Madillc29968b2016-01-20 11:17:23 -05002787 Offset destOffset(xoffset, yoffset, 0);
2788 Rectangle sourceArea(x, y, width, height);
2789
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002790 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002791 Texture *texture =
2792 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002793 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002794}
2795
2796void Context::copyTexSubImage3D(GLenum target,
2797 GLint level,
2798 GLint xoffset,
2799 GLint yoffset,
2800 GLint zoffset,
2801 GLint x,
2802 GLint y,
2803 GLsizei width,
2804 GLsizei height)
2805{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002806 if (width == 0 || height == 0)
2807 {
2808 return;
2809 }
2810
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002811 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002812 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002813
Jamie Madillc29968b2016-01-20 11:17:23 -05002814 Offset destOffset(xoffset, yoffset, zoffset);
2815 Rectangle sourceArea(x, y, width, height);
2816
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002817 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002818 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002819 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002820}
2821
2822void Context::framebufferTexture2D(GLenum target,
2823 GLenum attachment,
2824 GLenum textarget,
2825 GLuint texture,
2826 GLint level)
2827{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002828 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002829 ASSERT(framebuffer);
2830
2831 if (texture != 0)
2832 {
2833 Texture *textureObj = getTexture(texture);
2834
2835 ImageIndex index = ImageIndex::MakeInvalid();
2836
2837 if (textarget == GL_TEXTURE_2D)
2838 {
2839 index = ImageIndex::Make2D(level);
2840 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002841 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2842 {
2843 ASSERT(level == 0);
2844 index = ImageIndex::Make2DMultisample();
2845 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002846 else
2847 {
2848 ASSERT(IsCubeMapTextureTarget(textarget));
2849 index = ImageIndex::MakeCube(textarget, level);
2850 }
2851
Jamie Madilla02315b2017-02-23 14:14:47 -05002852 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002853 }
2854 else
2855 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002856 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002857 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002858
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002859 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002860}
2861
2862void Context::framebufferRenderbuffer(GLenum target,
2863 GLenum attachment,
2864 GLenum renderbuffertarget,
2865 GLuint renderbuffer)
2866{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002867 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002868 ASSERT(framebuffer);
2869
2870 if (renderbuffer != 0)
2871 {
2872 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002873
2874 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002875 renderbufferObject);
2876 }
2877 else
2878 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002879 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002880 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002881
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002882 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002883}
2884
2885void Context::framebufferTextureLayer(GLenum target,
2886 GLenum attachment,
2887 GLuint texture,
2888 GLint level,
2889 GLint layer)
2890{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002891 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002892 ASSERT(framebuffer);
2893
2894 if (texture != 0)
2895 {
2896 Texture *textureObject = getTexture(texture);
2897
2898 ImageIndex index = ImageIndex::MakeInvalid();
2899
2900 if (textureObject->getTarget() == GL_TEXTURE_3D)
2901 {
2902 index = ImageIndex::Make3D(level, layer);
2903 }
2904 else
2905 {
2906 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2907 index = ImageIndex::Make2DArray(level, layer);
2908 }
2909
Jamie Madilla02315b2017-02-23 14:14:47 -05002910 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002911 }
2912 else
2913 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002914 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002915 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002916
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002917 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002918}
2919
2920void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2921{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002922 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002923 ASSERT(framebuffer);
2924 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002925 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002926}
2927
2928void Context::readBuffer(GLenum mode)
2929{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002930 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002931 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002932 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002933}
2934
2935void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2936{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002937 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002938 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002939
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002940 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002941 ASSERT(framebuffer);
2942
2943 // The specification isn't clear what should be done when the framebuffer isn't complete.
2944 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002945 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002946}
2947
2948void Context::invalidateFramebuffer(GLenum target,
2949 GLsizei numAttachments,
2950 const GLenum *attachments)
2951{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002952 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002953 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002954
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002955 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002956 ASSERT(framebuffer);
2957
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002958 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002959 {
Jamie Madill437fa652016-05-03 15:13:24 -04002960 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002961 }
Jamie Madill437fa652016-05-03 15:13:24 -04002962
2963 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002964}
2965
2966void Context::invalidateSubFramebuffer(GLenum target,
2967 GLsizei numAttachments,
2968 const GLenum *attachments,
2969 GLint x,
2970 GLint y,
2971 GLsizei width,
2972 GLsizei height)
2973{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002974 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002975 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002976
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002977 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002978 ASSERT(framebuffer);
2979
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002980 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002981 {
Jamie Madill437fa652016-05-03 15:13:24 -04002982 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002983 }
Jamie Madill437fa652016-05-03 15:13:24 -04002984
2985 Rectangle area(x, y, width, height);
2986 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002987}
2988
Jamie Madill73a84962016-02-12 09:27:23 -05002989void Context::texImage2D(GLenum target,
2990 GLint level,
2991 GLint internalformat,
2992 GLsizei width,
2993 GLsizei height,
2994 GLint border,
2995 GLenum format,
2996 GLenum type,
2997 const GLvoid *pixels)
2998{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002999 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003000
3001 Extents size(width, height, 1);
3002 Texture *texture =
3003 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003004 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3005 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003006}
3007
3008void Context::texImage3D(GLenum target,
3009 GLint level,
3010 GLint internalformat,
3011 GLsizei width,
3012 GLsizei height,
3013 GLsizei depth,
3014 GLint border,
3015 GLenum format,
3016 GLenum type,
3017 const GLvoid *pixels)
3018{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003019 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003020
3021 Extents size(width, height, depth);
3022 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003023 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3024 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003025}
3026
3027void Context::texSubImage2D(GLenum target,
3028 GLint level,
3029 GLint xoffset,
3030 GLint yoffset,
3031 GLsizei width,
3032 GLsizei height,
3033 GLenum format,
3034 GLenum type,
3035 const GLvoid *pixels)
3036{
3037 // Zero sized uploads are valid but no-ops
3038 if (width == 0 || height == 0)
3039 {
3040 return;
3041 }
3042
Jamie Madillad9f24e2016-02-12 09:27:24 -05003043 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003044
3045 Box area(xoffset, yoffset, 0, width, height, 1);
3046 Texture *texture =
3047 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003048 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3049 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003050}
3051
3052void Context::texSubImage3D(GLenum target,
3053 GLint level,
3054 GLint xoffset,
3055 GLint yoffset,
3056 GLint zoffset,
3057 GLsizei width,
3058 GLsizei height,
3059 GLsizei depth,
3060 GLenum format,
3061 GLenum type,
3062 const GLvoid *pixels)
3063{
3064 // Zero sized uploads are valid but no-ops
3065 if (width == 0 || height == 0 || depth == 0)
3066 {
3067 return;
3068 }
3069
Jamie Madillad9f24e2016-02-12 09:27:24 -05003070 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003071
3072 Box area(xoffset, yoffset, zoffset, width, height, depth);
3073 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003074 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3075 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003076}
3077
3078void Context::compressedTexImage2D(GLenum target,
3079 GLint level,
3080 GLenum internalformat,
3081 GLsizei width,
3082 GLsizei height,
3083 GLint border,
3084 GLsizei imageSize,
3085 const GLvoid *data)
3086{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003087 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003088
3089 Extents size(width, height, 1);
3090 Texture *texture =
3091 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003092 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003093 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003094 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003095}
3096
3097void Context::compressedTexImage3D(GLenum target,
3098 GLint level,
3099 GLenum internalformat,
3100 GLsizei width,
3101 GLsizei height,
3102 GLsizei depth,
3103 GLint border,
3104 GLsizei imageSize,
3105 const GLvoid *data)
3106{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003107 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003108
3109 Extents size(width, height, depth);
3110 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003111 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003112 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003113 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003114}
3115
3116void Context::compressedTexSubImage2D(GLenum target,
3117 GLint level,
3118 GLint xoffset,
3119 GLint yoffset,
3120 GLsizei width,
3121 GLsizei height,
3122 GLenum format,
3123 GLsizei imageSize,
3124 const GLvoid *data)
3125{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003126 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003127
3128 Box area(xoffset, yoffset, 0, width, height, 1);
3129 Texture *texture =
3130 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003131 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003132 format, imageSize,
3133 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003134}
3135
3136void Context::compressedTexSubImage3D(GLenum target,
3137 GLint level,
3138 GLint xoffset,
3139 GLint yoffset,
3140 GLint zoffset,
3141 GLsizei width,
3142 GLsizei height,
3143 GLsizei depth,
3144 GLenum format,
3145 GLsizei imageSize,
3146 const GLvoid *data)
3147{
3148 // Zero sized uploads are valid but no-ops
3149 if (width == 0 || height == 0)
3150 {
3151 return;
3152 }
3153
Jamie Madillad9f24e2016-02-12 09:27:24 -05003154 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003155
3156 Box area(xoffset, yoffset, zoffset, width, height, depth);
3157 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003158 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003159 format, imageSize,
3160 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003161}
3162
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003163void Context::generateMipmap(GLenum target)
3164{
3165 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003166 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003167}
3168
Geoff Lang97073d12016-04-20 10:42:34 -07003169void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003170 GLint sourceLevel,
3171 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003172 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003173 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003174 GLint internalFormat,
3175 GLenum destType,
3176 GLboolean unpackFlipY,
3177 GLboolean unpackPremultiplyAlpha,
3178 GLboolean unpackUnmultiplyAlpha)
3179{
3180 syncStateForTexImage();
3181
3182 gl::Texture *sourceTexture = getTexture(sourceId);
3183 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003184 handleError(destTexture->copyTexture(
3185 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3186 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003187}
3188
3189void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003190 GLint sourceLevel,
3191 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003192 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003193 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003194 GLint xoffset,
3195 GLint yoffset,
3196 GLint x,
3197 GLint y,
3198 GLsizei width,
3199 GLsizei height,
3200 GLboolean unpackFlipY,
3201 GLboolean unpackPremultiplyAlpha,
3202 GLboolean unpackUnmultiplyAlpha)
3203{
3204 // Zero sized copies are valid but no-ops
3205 if (width == 0 || height == 0)
3206 {
3207 return;
3208 }
3209
3210 syncStateForTexImage();
3211
3212 gl::Texture *sourceTexture = getTexture(sourceId);
3213 gl::Texture *destTexture = getTexture(destId);
3214 Offset offset(xoffset, yoffset, 0);
3215 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003216 handleError(destTexture->copySubTexture(
3217 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3218 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003219}
3220
Geoff Lang47110bf2016-04-20 11:13:22 -07003221void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3222{
3223 syncStateForTexImage();
3224
3225 gl::Texture *sourceTexture = getTexture(sourceId);
3226 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003227 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003228}
3229
Geoff Lang496c02d2016-10-20 11:38:11 -07003230void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003231{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003232 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003233 ASSERT(buffer);
3234
Geoff Lang496c02d2016-10-20 11:38:11 -07003235 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003236}
3237
3238GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3239{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003240 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003241 ASSERT(buffer);
3242
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003243 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003244 if (error.isError())
3245 {
Jamie Madill437fa652016-05-03 15:13:24 -04003246 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003247 return nullptr;
3248 }
3249
3250 return buffer->getMapPointer();
3251}
3252
3253GLboolean Context::unmapBuffer(GLenum target)
3254{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003255 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003256 ASSERT(buffer);
3257
3258 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003259 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003260 if (error.isError())
3261 {
Jamie Madill437fa652016-05-03 15:13:24 -04003262 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003263 return GL_FALSE;
3264 }
3265
3266 return result;
3267}
3268
3269GLvoid *Context::mapBufferRange(GLenum target,
3270 GLintptr offset,
3271 GLsizeiptr length,
3272 GLbitfield access)
3273{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003274 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003275 ASSERT(buffer);
3276
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003277 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003278 if (error.isError())
3279 {
Jamie Madill437fa652016-05-03 15:13:24 -04003280 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003281 return nullptr;
3282 }
3283
3284 return buffer->getMapPointer();
3285}
3286
3287void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3288{
3289 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3290}
3291
Jamie Madillad9f24e2016-02-12 09:27:24 -05003292void Context::syncStateForReadPixels()
3293{
3294 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3295}
3296
3297void Context::syncStateForTexImage()
3298{
3299 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3300}
3301
3302void Context::syncStateForClear()
3303{
3304 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3305}
3306
3307void Context::syncStateForBlit()
3308{
3309 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3310}
3311
Jamie Madillc20ab272016-06-09 07:20:46 -07003312void Context::activeTexture(GLenum texture)
3313{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003314 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003315}
3316
3317void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3318{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003319 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003320}
3321
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003322void Context::blendEquation(GLenum mode)
3323{
3324 mGLState.setBlendEquation(mode, mode);
3325}
3326
Jamie Madillc20ab272016-06-09 07:20:46 -07003327void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3328{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003329 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003330}
3331
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003332void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3333{
3334 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3335}
3336
Jamie Madillc20ab272016-06-09 07:20:46 -07003337void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3338{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340}
3341
3342void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3343{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345}
3346
3347void Context::clearDepthf(GLclampf depth)
3348{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003350}
3351
3352void Context::clearStencil(GLint s)
3353{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003355}
3356
3357void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3358{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003359 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003360}
3361
3362void Context::cullFace(GLenum mode)
3363{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365}
3366
3367void Context::depthFunc(GLenum func)
3368{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370}
3371
3372void Context::depthMask(GLboolean flag)
3373{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003374 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003375}
3376
3377void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3378{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003379 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003380}
3381
3382void Context::disable(GLenum cap)
3383{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003384 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003385}
3386
3387void Context::disableVertexAttribArray(GLuint index)
3388{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003390}
3391
3392void Context::enable(GLenum cap)
3393{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003394 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003395}
3396
3397void Context::enableVertexAttribArray(GLuint index)
3398{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003400}
3401
3402void Context::frontFace(GLenum mode)
3403{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003404 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003405}
3406
3407void Context::hint(GLenum target, GLenum mode)
3408{
3409 switch (target)
3410 {
3411 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003412 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003413 break;
3414
3415 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003416 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003417 break;
3418
3419 default:
3420 UNREACHABLE();
3421 return;
3422 }
3423}
3424
3425void Context::lineWidth(GLfloat width)
3426{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003427 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003428}
3429
3430void Context::pixelStorei(GLenum pname, GLint param)
3431{
3432 switch (pname)
3433 {
3434 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003435 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003436 break;
3437
3438 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003439 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003440 break;
3441
3442 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003443 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003444 break;
3445
3446 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003447 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003448 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003449 break;
3450
3451 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003452 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003453 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003454 break;
3455
3456 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003457 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003458 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003459 break;
3460
3461 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003462 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003463 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003464 break;
3465
3466 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003467 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003468 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003469 break;
3470
3471 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003472 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003473 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003474 break;
3475
3476 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003477 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003478 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003479 break;
3480
3481 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003482 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484 break;
3485
3486 default:
3487 UNREACHABLE();
3488 return;
3489 }
3490}
3491
3492void Context::polygonOffset(GLfloat factor, GLfloat units)
3493{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003494 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003495}
3496
3497void Context::sampleCoverage(GLclampf value, GLboolean invert)
3498{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003499 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003500}
3501
3502void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3503{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003504 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003505}
3506
3507void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3508{
3509 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3510 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003511 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003512 }
3513
3514 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3515 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003516 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003517 }
3518}
3519
3520void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3521{
3522 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3523 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003524 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003525 }
3526
3527 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3528 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003530 }
3531}
3532
3533void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3534{
3535 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3536 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003538 }
3539
3540 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3541 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003542 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003543 }
3544}
3545
3546void Context::vertexAttrib1f(GLuint index, GLfloat x)
3547{
3548 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003550}
3551
3552void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3553{
3554 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003555 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003556}
3557
3558void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3559{
3560 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003561 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003562}
3563
3564void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3565{
3566 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003567 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003568}
3569
3570void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3571{
3572 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003573 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003574}
3575
3576void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3577{
3578 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003579 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003580}
3581
3582void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3583{
3584 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003585 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003586}
3587
3588void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3589{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003590 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003591}
3592
3593void Context::vertexAttribPointer(GLuint index,
3594 GLint size,
3595 GLenum type,
3596 GLboolean normalized,
3597 GLsizei stride,
3598 const GLvoid *ptr)
3599{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003600 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3601 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003602}
3603
Shao80957d92017-02-20 21:25:59 +08003604void Context::vertexAttribFormat(GLuint attribIndex,
3605 GLint size,
3606 GLenum type,
3607 GLboolean normalized,
3608 GLuint relativeOffset)
3609{
3610 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3611 relativeOffset);
3612}
3613
3614void Context::vertexAttribIFormat(GLuint attribIndex,
3615 GLint size,
3616 GLenum type,
3617 GLuint relativeOffset)
3618{
3619 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3620}
3621
3622void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3623{
3624 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3625}
3626
3627void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3628{
3629 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3630}
3631
Jamie Madillc20ab272016-06-09 07:20:46 -07003632void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3633{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003634 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003635}
3636
3637void Context::vertexAttribIPointer(GLuint index,
3638 GLint size,
3639 GLenum type,
3640 GLsizei stride,
3641 const GLvoid *pointer)
3642{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003643 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3644 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003645}
3646
3647void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3648{
3649 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003650 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003651}
3652
3653void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3654{
3655 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003656 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003657}
3658
3659void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3660{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003661 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003662}
3663
3664void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3665{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003666 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003667}
3668
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003669void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3670{
3671 const VertexAttribCurrentValueData &currentValues =
3672 getGLState().getVertexAttribCurrentValue(index);
3673 const VertexArray *vao = getGLState().getVertexArray();
3674 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3675 currentValues, pname, params);
3676}
3677
3678void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3679{
3680 const VertexAttribCurrentValueData &currentValues =
3681 getGLState().getVertexAttribCurrentValue(index);
3682 const VertexArray *vao = getGLState().getVertexArray();
3683 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3684 currentValues, pname, params);
3685}
3686
3687void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3688{
3689 const VertexAttribCurrentValueData &currentValues =
3690 getGLState().getVertexAttribCurrentValue(index);
3691 const VertexArray *vao = getGLState().getVertexArray();
3692 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3693 currentValues, pname, params);
3694}
3695
3696void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3697{
3698 const VertexAttribCurrentValueData &currentValues =
3699 getGLState().getVertexAttribCurrentValue(index);
3700 const VertexArray *vao = getGLState().getVertexArray();
3701 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3702 currentValues, pname, params);
3703}
3704
3705void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3706{
3707 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3708 QueryVertexAttribPointerv(attrib, pname, pointer);
3709}
3710
Jamie Madillc20ab272016-06-09 07:20:46 -07003711void Context::debugMessageControl(GLenum source,
3712 GLenum type,
3713 GLenum severity,
3714 GLsizei count,
3715 const GLuint *ids,
3716 GLboolean enabled)
3717{
3718 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003719 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3720 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003721}
3722
3723void Context::debugMessageInsert(GLenum source,
3724 GLenum type,
3725 GLuint id,
3726 GLenum severity,
3727 GLsizei length,
3728 const GLchar *buf)
3729{
3730 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003731 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003732}
3733
3734void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3735{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003736 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003737}
3738
3739GLuint Context::getDebugMessageLog(GLuint count,
3740 GLsizei bufSize,
3741 GLenum *sources,
3742 GLenum *types,
3743 GLuint *ids,
3744 GLenum *severities,
3745 GLsizei *lengths,
3746 GLchar *messageLog)
3747{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003748 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3749 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003750}
3751
3752void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3753{
3754 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003755 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003756}
3757
3758void Context::popDebugGroup()
3759{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003760 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003761}
3762
Jamie Madill29639852016-09-02 15:00:09 -04003763void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3764{
3765 Buffer *buffer = mGLState.getTargetBuffer(target);
3766 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003767 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003768}
3769
3770void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3771{
3772 if (data == nullptr)
3773 {
3774 return;
3775 }
3776
3777 Buffer *buffer = mGLState.getTargetBuffer(target);
3778 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003779 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003780}
3781
Jamie Madillef300b12016-10-07 15:12:09 -04003782void Context::attachShader(GLuint program, GLuint shader)
3783{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003784 auto programObject = mState.mShaderPrograms->getProgram(program);
3785 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003786 ASSERT(programObject && shaderObject);
3787 programObject->attachShader(shaderObject);
3788}
3789
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003790const Workarounds &Context::getWorkarounds() const
3791{
3792 return mWorkarounds;
3793}
3794
Jamie Madillb0817d12016-11-01 15:48:31 -04003795void Context::copyBufferSubData(GLenum readTarget,
3796 GLenum writeTarget,
3797 GLintptr readOffset,
3798 GLintptr writeOffset,
3799 GLsizeiptr size)
3800{
3801 // if size is zero, the copy is a successful no-op
3802 if (size == 0)
3803 {
3804 return;
3805 }
3806
3807 // TODO(jmadill): cache these.
3808 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3809 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3810
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003811 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003812}
3813
Jamie Madill01a80ee2016-11-07 12:06:18 -05003814void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3815{
3816 Program *programObject = getProgram(program);
3817 // TODO(jmadill): Re-use this from the validation if possible.
3818 ASSERT(programObject);
3819 programObject->bindAttributeLocation(index, name);
3820}
3821
3822void Context::bindBuffer(GLenum target, GLuint buffer)
3823{
3824 switch (target)
3825 {
3826 case GL_ARRAY_BUFFER:
3827 bindArrayBuffer(buffer);
3828 break;
3829 case GL_ELEMENT_ARRAY_BUFFER:
3830 bindElementArrayBuffer(buffer);
3831 break;
3832 case GL_COPY_READ_BUFFER:
3833 bindCopyReadBuffer(buffer);
3834 break;
3835 case GL_COPY_WRITE_BUFFER:
3836 bindCopyWriteBuffer(buffer);
3837 break;
3838 case GL_PIXEL_PACK_BUFFER:
3839 bindPixelPackBuffer(buffer);
3840 break;
3841 case GL_PIXEL_UNPACK_BUFFER:
3842 bindPixelUnpackBuffer(buffer);
3843 break;
3844 case GL_UNIFORM_BUFFER:
3845 bindGenericUniformBuffer(buffer);
3846 break;
3847 case GL_TRANSFORM_FEEDBACK_BUFFER:
3848 bindGenericTransformFeedbackBuffer(buffer);
3849 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003850 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003851 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003852 break;
3853 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003854 if (buffer != 0)
3855 {
3856 // Binding buffers to this binding point is not implemented yet.
3857 UNIMPLEMENTED();
3858 }
Geoff Lang3b573612016-10-31 14:08:10 -04003859 break;
3860 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003861 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003862 break;
3863 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003864 if (buffer != 0)
3865 {
3866 // Binding buffers to this binding point is not implemented yet.
3867 UNIMPLEMENTED();
3868 }
Geoff Lang3b573612016-10-31 14:08:10 -04003869 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003870
3871 default:
3872 UNREACHABLE();
3873 break;
3874 }
3875}
3876
Jiajia Qin6eafb042016-12-27 17:04:07 +08003877void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3878{
3879 bindBufferRange(target, index, buffer, 0, 0);
3880}
3881
3882void Context::bindBufferRange(GLenum target,
3883 GLuint index,
3884 GLuint buffer,
3885 GLintptr offset,
3886 GLsizeiptr size)
3887{
3888 switch (target)
3889 {
3890 case GL_TRANSFORM_FEEDBACK_BUFFER:
3891 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3892 bindGenericTransformFeedbackBuffer(buffer);
3893 break;
3894 case GL_UNIFORM_BUFFER:
3895 bindIndexedUniformBuffer(buffer, index, offset, size);
3896 bindGenericUniformBuffer(buffer);
3897 break;
3898 case GL_ATOMIC_COUNTER_BUFFER:
3899 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3900 bindGenericAtomicCounterBuffer(buffer);
3901 break;
3902 case GL_SHADER_STORAGE_BUFFER:
3903 if (buffer != 0)
3904 {
3905 // Binding buffers to this binding point is not implemented yet.
3906 UNIMPLEMENTED();
3907 }
3908 break;
3909 default:
3910 UNREACHABLE();
3911 break;
3912 }
3913}
3914
Jamie Madill01a80ee2016-11-07 12:06:18 -05003915void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3916{
3917 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3918 {
3919 bindReadFramebuffer(framebuffer);
3920 }
3921
3922 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3923 {
3924 bindDrawFramebuffer(framebuffer);
3925 }
3926}
3927
3928void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3929{
3930 ASSERT(target == GL_RENDERBUFFER);
3931 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003932 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003933 mGLState.setRenderbufferBinding(object);
3934}
3935
JiangYizhoubddc46b2016-12-09 09:50:51 +08003936void Context::texStorage2DMultisample(GLenum target,
3937 GLsizei samples,
3938 GLenum internalformat,
3939 GLsizei width,
3940 GLsizei height,
3941 GLboolean fixedsamplelocations)
3942{
3943 Extents size(width, height, 1);
3944 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003945 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003946 fixedsamplelocations));
3947}
3948
3949void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3950{
3951 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3952 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3953
3954 switch (pname)
3955 {
3956 case GL_SAMPLE_POSITION:
3957 handleError(framebuffer->getSamplePosition(index, val));
3958 break;
3959 default:
3960 UNREACHABLE();
3961 }
3962}
3963
Jamie Madille8fb6402017-02-14 17:56:40 -05003964void Context::renderbufferStorage(GLenum target,
3965 GLenum internalformat,
3966 GLsizei width,
3967 GLsizei height)
3968{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003969 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3970 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3971
Jamie Madille8fb6402017-02-14 17:56:40 -05003972 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003973 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003974}
3975
3976void Context::renderbufferStorageMultisample(GLenum target,
3977 GLsizei samples,
3978 GLenum internalformat,
3979 GLsizei width,
3980 GLsizei height)
3981{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003982 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3983 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05003984
3985 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003986 handleError(
3987 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003988}
3989
JiangYizhoue18e6392017-02-20 10:32:23 +08003990void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
3991{
3992 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3993 QueryFramebufferParameteriv(framebuffer, pname, params);
3994}
3995
3996void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
3997{
3998 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3999 SetFramebufferParameteri(framebuffer, pname, param);
4000}
4001
Jamie Madille14951e2017-03-09 18:55:16 -05004002Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4003{
4004 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4005 {
4006 return gl::OutOfMemory() << "Failed to allocate internal buffer.";
4007 }
4008 return gl::NoError();
4009}
4010
Jamie Madillc29968b2016-01-20 11:17:23 -05004011} // namespace gl