blob: 02f7c830931aba86cda75b202d800eaa125ca26e [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jiawei-Shao2597fb62016-12-09 16:38:02 +080029#include "libANGLE/queryutils.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
37#include "libANGLE/formatutils.h"
38#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070039#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040040#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040041#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030042#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040043#include "libANGLE/queryutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Ian Ewell3ffd78b2016-01-22 16:09:42 -050048template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050049std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030050 GLsizei numPaths,
51 const void *paths,
52 GLuint pathBase)
53{
54 std::vector<gl::Path *> ret;
55 ret.reserve(numPaths);
56
57 const auto *nameArray = static_cast<const T *>(paths);
58
59 for (GLsizei i = 0; i < numPaths; ++i)
60 {
61 const GLuint pathName = nameArray[i] + pathBase;
62
63 ret.push_back(resourceManager.getPath(pathName));
64 }
65
66 return ret;
67}
68
Geoff Lang4ddf5af2016-12-01 14:30:44 -050069std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030070 GLsizei numPaths,
71 GLenum pathNameType,
72 const void *paths,
73 GLuint pathBase)
74{
75 switch (pathNameType)
76 {
77 case GL_UNSIGNED_BYTE:
78 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_BYTE:
81 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_UNSIGNED_SHORT:
84 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_SHORT:
87 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_INT:
90 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_INT:
93 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
94 }
95
96 UNREACHABLE();
97 return std::vector<gl::Path *>();
98}
99
100template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400101gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500102{
Geoff Lang2186c382016-10-14 10:54:54 -0400103 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500104
105 switch (pname)
106 {
107 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400108 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109 case GL_QUERY_RESULT_AVAILABLE_EXT:
110 {
111 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400112 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500113 if (!error.isError())
114 {
Geoff Lang2186c382016-10-14 10:54:54 -0400115 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500116 }
117 return error;
118 }
119 default:
120 UNREACHABLE();
121 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
122 }
123}
124
Geoff Langf6db0982015-08-25 13:04:00 -0400125void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
126{
Geoff Lang1a683462015-09-29 15:09:59 -0400127 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400128 {
129 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
130 tfBufferIndex++)
131 {
132 const OffsetBindingPointer<gl::Buffer> &buffer =
133 transformFeedback->getIndexedBuffer(tfBufferIndex);
134 if (buffer.get() != nullptr)
135 {
136 buffer->onTransformFeedback();
137 }
138 }
139 }
140}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141
142// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300143EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400145 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146}
147
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
149{
150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
151}
152
Geoff Langeb66a6e2016-10-31 13:06:12 -0400153gl::Version GetClientVersion(const egl::AttributeMap &attribs)
154{
155 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
156}
157
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500158GLenum GetResetStrategy(const egl::AttributeMap &attribs)
159{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400160 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
161 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500162 switch (attrib)
163 {
164 case EGL_NO_RESET_NOTIFICATION:
165 return GL_NO_RESET_NOTIFICATION_EXT;
166 case EGL_LOSE_CONTEXT_ON_RESET:
167 return GL_LOSE_CONTEXT_ON_RESET_EXT;
168 default:
169 UNREACHABLE();
170 return GL_NONE;
171 }
172}
173
174bool GetRobustAccess(const egl::AttributeMap &attribs)
175{
Geoff Lang077f20a2016-11-01 10:08:02 -0400176 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
177 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
178 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500179}
180
181bool GetDebug(const egl::AttributeMap &attribs)
182{
Geoff Lang077f20a2016-11-01 10:08:02 -0400183 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
184 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetNoError(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
190}
191
Geoff Langc287ea62016-09-16 14:46:51 -0400192bool GetWebGLContext(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langf41a7152016-09-19 15:11:17 -0400197bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
200}
201
Geoff Langfeb8c682017-02-13 16:07:35 -0500202bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
205}
206
Jamie Madille08a1d32017-03-07 17:24:06 -0500207bool GetRobustResourceInit(const egl::AttributeMap &attribs)
208{
209 return (attribs.get(EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
210}
211
Martin Radev9d901792016-07-15 15:58:58 +0300212std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
213{
214 std::string labelName;
215 if (label != nullptr)
216 {
217 size_t labelLength = length < 0 ? strlen(label) : length;
218 labelName = std::string(label, labelLength);
219 }
220 return labelName;
221}
222
223void GetObjectLabelBase(const std::string &objectLabel,
224 GLsizei bufSize,
225 GLsizei *length,
226 GLchar *label)
227{
228 size_t writeLength = objectLabel.length();
229 if (label != nullptr && bufSize > 0)
230 {
231 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
232 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
233 label[writeLength] = '\0';
234 }
235
236 if (length != nullptr)
237 {
238 *length = static_cast<GLsizei>(writeLength);
239 }
240}
241
Geoff Langf6db0982015-08-25 13:04:00 -0400242} // anonymous namespace
243
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000244namespace gl
245{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000246
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400247Context::Context(rx::EGLImplFactory *implFactory,
248 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400249 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500250 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500251 const egl::AttributeMap &attribs,
252 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300253
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500254 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500255 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500256 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700257 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500258 mCaps,
259 mTextureCaps,
260 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500261 mLimitations,
262 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700263 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500264 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400265 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500266 mClientType(EGL_OPENGL_ES_API),
267 mHasBeenCurrent(false),
268 mContextLost(false),
269 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700270 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500271 mResetStrategy(GetResetStrategy(attribs)),
272 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500273 mCurrentSurface(nullptr),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500274 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500275 mWebGLContext(GetWebGLContext(attribs)),
276 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277{
Geoff Lang077f20a2016-11-01 10:08:02 -0400278 if (mRobustAccess)
279 {
280 UNIMPLEMENTED();
281 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500283 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700284 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400285
Geoff Langeb66a6e2016-10-31 13:06:12 -0400286 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Jamie Madille08a1d32017-03-07 17:24:06 -0500287 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs),
288 GetRobustResourceInit(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100289
Shannon Woods53a94a82014-06-24 15:20:36 -0400290 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400291
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000292 // [OpenGL ES 2.0.24] section 3.7 page 83:
293 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
294 // and cube map texture state vectors respectively associated with them.
295 // In order that access to these initial textures not be lost, they are treated as texture
296 // objects all of whose names are 0.
297
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400298 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500300
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400301 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500302 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400303
Geoff Langeb66a6e2016-10-31 13:06:12 -0400304 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400305 {
306 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500308 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400309
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400310 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500311 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312 }
Geoff Lang3b573612016-10-31 14:08:10 -0400313 if (getClientVersion() >= Version(3, 1))
314 {
315 Texture *zeroTexture2DMultisample =
316 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
317 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800318
319 bindGenericAtomicCounterBuffer(0);
320 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
321 {
322 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
323 }
Geoff Lang3b573612016-10-31 14:08:10 -0400324 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000325
Ian Ewellbda75592016-04-18 17:25:54 -0400326 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
327 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400328 Texture *zeroTextureExternal =
329 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400330 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
331 }
332
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700333 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500334
Jamie Madill57a89722013-07-02 11:57:03 -0400335 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000336 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800337 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000338 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400339
Jamie Madill01a80ee2016-11-07 12:06:18 -0500340 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000341
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000342 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500343 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000344 {
345 bindIndexedUniformBuffer(0, i, 0, -1);
346 }
347
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000348 bindCopyReadBuffer(0);
349 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000350 bindPixelPackBuffer(0);
351 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000352
Geoff Langeb66a6e2016-10-31 13:06:12 -0400353 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400354 {
355 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
356 // In the initial state, a default transform feedback object is bound and treated as
357 // a transform feedback object with a name of zero. That object is bound any time
358 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400359 bindTransformFeedback(0);
360 }
Geoff Langc8058452014-02-03 12:04:11 -0500361
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700362 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500363
364 // Initialize dirty bit masks
365 // TODO(jmadill): additional ES3 state
366 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
367 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
368 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
369 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500373 // No dirty objects.
374
375 // Readpixels uses the pack state and read FBO
376 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
377 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
378 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
379 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500382 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
383
384 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
385 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
386 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
387 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
388 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
389 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
390 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
391 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
392 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
393 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
394 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
395 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
396
397 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
398 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700399 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500400 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
401 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400402
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400403 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000404}
405
Jamie Madill70ee0f62017-02-06 16:04:20 -0500406void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500408 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000409
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000411 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400412 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000413 }
414
Corentin Wallez80b24112015-08-25 16:41:57 -0400415 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000416 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400417 if (query.second != nullptr)
418 {
419 query.second->release();
420 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421 }
422
Corentin Wallez80b24112015-08-25 16:41:57 -0400423 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400424 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400425 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400426 }
427
Corentin Wallez80b24112015-08-25 16:41:57 -0400428 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500429 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500430 if (transformFeedback.second != nullptr)
431 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500432 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500433 }
Geoff Langc8058452014-02-03 12:04:11 -0500434 }
435
Jamie Madilldedd7b92014-11-05 16:30:36 -0500436 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400437 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500438 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400439 }
440 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000441
Corentin Wallezccab69d2017-01-27 16:57:15 -0500442 SafeDelete(mSurfacelessFramebuffer);
443
Jamie Madill70ee0f62017-02-06 16:04:20 -0500444 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400445
Geoff Lang492a7e42014-11-05 13:27:06 -0500446 SafeDelete(mCompiler);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500447
448 mState.mBuffers->release(this);
449 mState.mShaderPrograms->release(this);
450 mState.mTextures->release(this);
451 mState.mRenderbuffers->release(this);
452 mState.mSamplers->release(this);
453 mState.mFenceSyncs->release(this);
454 mState.mPaths->release(this);
455 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000456}
457
Jamie Madill70ee0f62017-02-06 16:04:20 -0500458Context::~Context()
459{
460}
461
462void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000464 if (!mHasBeenCurrent)
465 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000466 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500467 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400468 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000469
Corentin Wallezc295e512017-01-27 17:47:50 -0500470 int width = 0;
471 int height = 0;
472 if (surface != nullptr)
473 {
474 width = surface->getWidth();
475 height = surface->getHeight();
476 }
477
478 mGLState.setViewportParams(0, 0, width, height);
479 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000480
481 mHasBeenCurrent = true;
482 }
483
Jamie Madill1b94d432015-08-07 13:23:23 -0400484 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700485 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400486
Jamie Madill70ee0f62017-02-06 16:04:20 -0500487 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500488
489 Framebuffer *newDefault = nullptr;
490 if (surface != nullptr)
491 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500492 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500493 mCurrentSurface = surface;
494 newDefault = surface->getDefaultFramebuffer();
495 }
496 else
497 {
498 if (mSurfacelessFramebuffer == nullptr)
499 {
500 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
501 }
502
503 newDefault = mSurfacelessFramebuffer;
504 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000505
Corentin Wallez37c39792015-08-20 14:19:46 -0400506 // Update default framebuffer, the binding of the previous default
507 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400508 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700509 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400510 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700511 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400512 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700513 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400514 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700515 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400516 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500517 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400518 }
Ian Ewell292f0052016-02-04 10:37:32 -0500519
520 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700521 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000522}
523
Jamie Madill70ee0f62017-02-06 16:04:20 -0500524void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400525{
Corentin Wallez37c39792015-08-20 14:19:46 -0400526 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500527 Framebuffer *currentDefault = nullptr;
528 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400529 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500530 currentDefault = mCurrentSurface->getDefaultFramebuffer();
531 }
532 else if (mSurfacelessFramebuffer != nullptr)
533 {
534 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400535 }
536
Corentin Wallezc295e512017-01-27 17:47:50 -0500537 if (mGLState.getReadFramebuffer() == currentDefault)
538 {
539 mGLState.setReadFramebufferBinding(nullptr);
540 }
541 if (mGLState.getDrawFramebuffer() == currentDefault)
542 {
543 mGLState.setDrawFramebufferBinding(nullptr);
544 }
545 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
546
547 if (mCurrentSurface)
548 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500549 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500550 mCurrentSurface = nullptr;
551 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400552}
553
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000554GLuint Context::createBuffer()
555{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500556 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000557}
558
559GLuint Context::createProgram()
560{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500561 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000562}
563
564GLuint Context::createShader(GLenum type)
565{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500566 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000567}
568
569GLuint Context::createTexture()
570{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500571 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000572}
573
574GLuint Context::createRenderbuffer()
575{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500576 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000577}
578
Geoff Lang882033e2014-09-30 11:26:07 -0400579GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400580{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500581 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400582
Cooper Partind8e62a32015-01-29 15:21:25 -0800583 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400584}
585
Sami Väisänene45e53b2016-05-25 10:36:04 +0300586GLuint Context::createPaths(GLsizei range)
587{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500588 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300589 if (resultOrError.isError())
590 {
591 handleError(resultOrError.getError());
592 return 0;
593 }
594 return resultOrError.getResult();
595}
596
Jamie Madill57a89722013-07-02 11:57:03 -0400597GLuint Context::createVertexArray()
598{
Geoff Lang36167ab2015-12-07 10:27:14 -0500599 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
600 mVertexArrayMap[vertexArray] = nullptr;
601 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400602}
603
Jamie Madilldc356042013-07-19 16:36:57 -0400604GLuint Context::createSampler()
605{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500606 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400607}
608
Geoff Langc8058452014-02-03 12:04:11 -0500609GLuint Context::createTransformFeedback()
610{
Geoff Lang36167ab2015-12-07 10:27:14 -0500611 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
612 mTransformFeedbackMap[transformFeedback] = nullptr;
613 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500614}
615
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000616// Returns an unused framebuffer name
617GLuint Context::createFramebuffer()
618{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500619 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620}
621
Jamie Madill33dc8432013-07-26 11:55:05 -0400622GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000623{
Jamie Madill33dc8432013-07-26 11:55:05 -0400624 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400626 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000627
628 return handle;
629}
630
631// Returns an unused query name
632GLuint Context::createQuery()
633{
634 GLuint handle = mQueryHandleAllocator.allocate();
635
636 mQueryMap[handle] = NULL;
637
638 return handle;
639}
640
641void Context::deleteBuffer(GLuint buffer)
642{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500643 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000644 {
645 detachBuffer(buffer);
646 }
Jamie Madill893ab082014-05-16 16:56:10 -0400647
Jamie Madill6c1f6712017-02-14 19:08:04 -0500648 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000649}
650
651void Context::deleteShader(GLuint shader)
652{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500653 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000654}
655
656void Context::deleteProgram(GLuint program)
657{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500658 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659}
660
661void Context::deleteTexture(GLuint texture)
662{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500663 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000664 {
665 detachTexture(texture);
666 }
667
Jamie Madill6c1f6712017-02-14 19:08:04 -0500668 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000669}
670
671void Context::deleteRenderbuffer(GLuint renderbuffer)
672{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500673 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000674 {
675 detachRenderbuffer(renderbuffer);
676 }
Jamie Madill893ab082014-05-16 16:56:10 -0400677
Jamie Madill6c1f6712017-02-14 19:08:04 -0500678 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000679}
680
Jamie Madillcd055f82013-07-26 11:55:15 -0400681void Context::deleteFenceSync(GLsync fenceSync)
682{
683 // The spec specifies the underlying Fence object is not deleted until all current
684 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
685 // and since our API is currently designed for being called from a single thread, we can delete
686 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500687 mState.mFenceSyncs->deleteObject(this,
688 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400689}
690
Sami Väisänene45e53b2016-05-25 10:36:04 +0300691void Context::deletePaths(GLuint first, GLsizei range)
692{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500693 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300694}
695
696bool Context::hasPathData(GLuint path) const
697{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500698 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300699 if (pathObj == nullptr)
700 return false;
701
702 return pathObj->hasPathData();
703}
704
705bool Context::hasPath(GLuint path) const
706{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500707 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300708}
709
710void Context::setPathCommands(GLuint path,
711 GLsizei numCommands,
712 const GLubyte *commands,
713 GLsizei numCoords,
714 GLenum coordType,
715 const void *coords)
716{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500717 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300718
719 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
720}
721
722void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
723{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500724 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300725
726 switch (pname)
727 {
728 case GL_PATH_STROKE_WIDTH_CHROMIUM:
729 pathObj->setStrokeWidth(value);
730 break;
731 case GL_PATH_END_CAPS_CHROMIUM:
732 pathObj->setEndCaps(static_cast<GLenum>(value));
733 break;
734 case GL_PATH_JOIN_STYLE_CHROMIUM:
735 pathObj->setJoinStyle(static_cast<GLenum>(value));
736 break;
737 case GL_PATH_MITER_LIMIT_CHROMIUM:
738 pathObj->setMiterLimit(value);
739 break;
740 case GL_PATH_STROKE_BOUND_CHROMIUM:
741 pathObj->setStrokeBound(value);
742 break;
743 default:
744 UNREACHABLE();
745 break;
746 }
747}
748
749void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
750{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500751 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300752
753 switch (pname)
754 {
755 case GL_PATH_STROKE_WIDTH_CHROMIUM:
756 *value = pathObj->getStrokeWidth();
757 break;
758 case GL_PATH_END_CAPS_CHROMIUM:
759 *value = static_cast<GLfloat>(pathObj->getEndCaps());
760 break;
761 case GL_PATH_JOIN_STYLE_CHROMIUM:
762 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
763 break;
764 case GL_PATH_MITER_LIMIT_CHROMIUM:
765 *value = pathObj->getMiterLimit();
766 break;
767 case GL_PATH_STROKE_BOUND_CHROMIUM:
768 *value = pathObj->getStrokeBound();
769 break;
770 default:
771 UNREACHABLE();
772 break;
773 }
774}
775
776void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
777{
778 mGLState.setPathStencilFunc(func, ref, mask);
779}
780
Jamie Madill57a89722013-07-02 11:57:03 -0400781void Context::deleteVertexArray(GLuint vertexArray)
782{
Geoff Lang36167ab2015-12-07 10:27:14 -0500783 auto iter = mVertexArrayMap.find(vertexArray);
784 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000785 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500786 VertexArray *vertexArrayObject = iter->second;
787 if (vertexArrayObject != nullptr)
788 {
789 detachVertexArray(vertexArray);
790 delete vertexArrayObject;
791 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000792
Geoff Lang36167ab2015-12-07 10:27:14 -0500793 mVertexArrayMap.erase(iter);
794 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400795 }
796}
797
Jamie Madilldc356042013-07-19 16:36:57 -0400798void Context::deleteSampler(GLuint sampler)
799{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500800 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400801 {
802 detachSampler(sampler);
803 }
804
Jamie Madill6c1f6712017-02-14 19:08:04 -0500805 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400806}
807
Geoff Langc8058452014-02-03 12:04:11 -0500808void Context::deleteTransformFeedback(GLuint transformFeedback)
809{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500810 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500811 if (iter != mTransformFeedbackMap.end())
812 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500813 TransformFeedback *transformFeedbackObject = iter->second;
814 if (transformFeedbackObject != nullptr)
815 {
816 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500817 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500818 }
819
Geoff Lang50b3fe82015-12-08 14:49:12 +0000820 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500821 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500822 }
823}
824
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825void Context::deleteFramebuffer(GLuint framebuffer)
826{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500827 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000828 {
829 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000830 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500831
Jamie Madill6c1f6712017-02-14 19:08:04 -0500832 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000833}
834
Jamie Madill33dc8432013-07-26 11:55:05 -0400835void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000836{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500837 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000838
Jamie Madill33dc8432013-07-26 11:55:05 -0400839 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400841 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000842 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400843 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000844 }
845}
846
847void Context::deleteQuery(GLuint query)
848{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500849 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850 if (queryObject != mQueryMap.end())
851 {
852 mQueryHandleAllocator.release(queryObject->first);
853 if (queryObject->second)
854 {
855 queryObject->second->release();
856 }
857 mQueryMap.erase(queryObject);
858 }
859}
860
Geoff Lang70d0f492015-12-10 17:45:46 -0500861Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000862{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500863 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000864}
865
Jamie Madill570f7c82014-07-03 10:38:54 -0400866Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000867{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500868 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000869}
870
Geoff Lang70d0f492015-12-10 17:45:46 -0500871Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000872{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500873 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000874}
875
Jamie Madillcd055f82013-07-26 11:55:15 -0400876FenceSync *Context::getFenceSync(GLsync handle) const
877{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500878 return mState.mFenceSyncs->getFenceSync(
879 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400880}
881
Jamie Madill57a89722013-07-02 11:57:03 -0400882VertexArray *Context::getVertexArray(GLuint handle) const
883{
884 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500885 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400886}
887
Jamie Madilldc356042013-07-19 16:36:57 -0400888Sampler *Context::getSampler(GLuint handle) const
889{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500890 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400891}
892
Geoff Langc8058452014-02-03 12:04:11 -0500893TransformFeedback *Context::getTransformFeedback(GLuint handle) const
894{
Geoff Lang36167ab2015-12-07 10:27:14 -0500895 auto iter = mTransformFeedbackMap.find(handle);
896 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500897}
898
Geoff Lang70d0f492015-12-10 17:45:46 -0500899LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
900{
901 switch (identifier)
902 {
903 case GL_BUFFER:
904 return getBuffer(name);
905 case GL_SHADER:
906 return getShader(name);
907 case GL_PROGRAM:
908 return getProgram(name);
909 case GL_VERTEX_ARRAY:
910 return getVertexArray(name);
911 case GL_QUERY:
912 return getQuery(name);
913 case GL_TRANSFORM_FEEDBACK:
914 return getTransformFeedback(name);
915 case GL_SAMPLER:
916 return getSampler(name);
917 case GL_TEXTURE:
918 return getTexture(name);
919 case GL_RENDERBUFFER:
920 return getRenderbuffer(name);
921 case GL_FRAMEBUFFER:
922 return getFramebuffer(name);
923 default:
924 UNREACHABLE();
925 return nullptr;
926 }
927}
928
929LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
930{
931 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
932}
933
Martin Radev9d901792016-07-15 15:58:58 +0300934void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
935{
936 LabeledObject *object = getLabeledObject(identifier, name);
937 ASSERT(object != nullptr);
938
939 std::string labelName = GetObjectLabelFromPointer(length, label);
940 object->setLabel(labelName);
941}
942
943void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
944{
945 LabeledObject *object = getLabeledObjectFromPtr(ptr);
946 ASSERT(object != nullptr);
947
948 std::string labelName = GetObjectLabelFromPointer(length, label);
949 object->setLabel(labelName);
950}
951
952void Context::getObjectLabel(GLenum identifier,
953 GLuint name,
954 GLsizei bufSize,
955 GLsizei *length,
956 GLchar *label) const
957{
958 LabeledObject *object = getLabeledObject(identifier, name);
959 ASSERT(object != nullptr);
960
961 const std::string &objectLabel = object->getLabel();
962 GetObjectLabelBase(objectLabel, bufSize, length, label);
963}
964
965void Context::getObjectPtrLabel(const void *ptr,
966 GLsizei bufSize,
967 GLsizei *length,
968 GLchar *label) const
969{
970 LabeledObject *object = getLabeledObjectFromPtr(ptr);
971 ASSERT(object != nullptr);
972
973 const std::string &objectLabel = object->getLabel();
974 GetObjectLabelBase(objectLabel, bufSize, length, label);
975}
976
Jamie Madilldc356042013-07-19 16:36:57 -0400977bool Context::isSampler(GLuint samplerName) const
978{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500979 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400980}
981
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500982void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000983{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500984 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700985 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000986}
987
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800988void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
989{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500990 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800991 mGLState.setDrawIndirectBufferBinding(buffer);
992}
993
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500994void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500996 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700997 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000998}
999
Jamie Madilldedd7b92014-11-05 16:30:36 -05001000void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001001{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001002 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001003
Jamie Madilldedd7b92014-11-05 16:30:36 -05001004 if (handle == 0)
1005 {
1006 texture = mZeroTextures[target].get();
1007 }
1008 else
1009 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001010 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001011 }
1012
1013 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001014 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001015}
1016
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001017void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001018{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001019 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1020 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001022}
1023
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001024void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001025{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001026 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1027 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001028 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001029}
1030
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001031void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001032{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001033 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001034 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001038{
Geoff Lang76b10c92014-09-05 16:28:14 -04001039 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001040 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001041 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001042 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001043}
1044
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001045void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001046{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001047 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001048 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001049}
1050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001051void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1052 GLuint index,
1053 GLintptr offset,
1054 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001055{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001056 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001057 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001061{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001062 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1067 GLuint index,
1068 GLintptr offset,
1069 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001070{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001071 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001072 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001073}
1074
Jiajia Qin6eafb042016-12-27 17:04:07 +08001075void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1076{
1077 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1078 mGLState.setGenericAtomicCounterBufferBinding(buffer);
1079}
1080
1081void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1082 GLuint index,
1083 GLintptr offset,
1084 GLsizeiptr size)
1085{
1086 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1087 mGLState.setIndexedAtomicCounterBufferBinding(index, buffer, offset, size);
1088}
1089
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001090void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001091{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001092 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001093 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001094}
1095
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001096void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001097{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001098 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001099 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001100}
1101
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001102void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001103{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001104 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001105 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001106}
1107
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001108void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001109{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001110 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001111 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001112}
1113
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001114void Context::useProgram(GLuint program)
1115{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001116 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001117}
1118
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001119void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001120{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001121 TransformFeedback *transformFeedback =
1122 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001123 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001124}
1125
Geoff Lang5aad9672014-09-08 11:10:42 -04001126Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001127{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001128 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001129 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001130
Geoff Lang5aad9672014-09-08 11:10:42 -04001131 // begin query
1132 Error error = queryObject->begin();
1133 if (error.isError())
1134 {
1135 return error;
1136 }
1137
1138 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001139 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001140
He Yunchaoacd18982017-01-04 10:46:42 +08001141 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001142}
1143
Geoff Lang5aad9672014-09-08 11:10:42 -04001144Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001145{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001146 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001147 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001148
Geoff Lang5aad9672014-09-08 11:10:42 -04001149 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001150
Geoff Lang5aad9672014-09-08 11:10:42 -04001151 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001152 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001153
1154 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001155}
1156
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001157Error Context::queryCounter(GLuint id, GLenum target)
1158{
1159 ASSERT(target == GL_TIMESTAMP_EXT);
1160
1161 Query *queryObject = getQuery(id, true, target);
1162 ASSERT(queryObject);
1163
1164 return queryObject->queryCounter();
1165}
1166
1167void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1168{
1169 switch (pname)
1170 {
1171 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001172 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001173 break;
1174 case GL_QUERY_COUNTER_BITS_EXT:
1175 switch (target)
1176 {
1177 case GL_TIME_ELAPSED_EXT:
1178 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1179 break;
1180 case GL_TIMESTAMP_EXT:
1181 params[0] = getExtensions().queryCounterBitsTimestamp;
1182 break;
1183 default:
1184 UNREACHABLE();
1185 params[0] = 0;
1186 break;
1187 }
1188 break;
1189 default:
1190 UNREACHABLE();
1191 return;
1192 }
1193}
1194
Geoff Lang2186c382016-10-14 10:54:54 -04001195void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001196{
Geoff Lang2186c382016-10-14 10:54:54 -04001197 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001198}
1199
Geoff Lang2186c382016-10-14 10:54:54 -04001200void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001201{
Geoff Lang2186c382016-10-14 10:54:54 -04001202 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001203}
1204
Geoff Lang2186c382016-10-14 10:54:54 -04001205void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001206{
Geoff Lang2186c382016-10-14 10:54:54 -04001207 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001208}
1209
Geoff Lang2186c382016-10-14 10:54:54 -04001210void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001211{
Geoff Lang2186c382016-10-14 10:54:54 -04001212 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001213}
1214
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001215Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001217 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218}
1219
Jamie Madill33dc8432013-07-26 11:55:05 -04001220FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001221{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001222 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223
Jamie Madill33dc8432013-07-26 11:55:05 -04001224 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225 {
1226 return NULL;
1227 }
1228 else
1229 {
1230 return fence->second;
1231 }
1232}
1233
1234Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1235{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001236 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237
1238 if (query == mQueryMap.end())
1239 {
1240 return NULL;
1241 }
1242 else
1243 {
1244 if (!query->second && create)
1245 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001246 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001247 query->second->addRef();
1248 }
1249 return query->second;
1250 }
1251}
1252
Geoff Lang70d0f492015-12-10 17:45:46 -05001253Query *Context::getQuery(GLuint handle) const
1254{
1255 auto iter = mQueryMap.find(handle);
1256 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1257}
1258
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001259Texture *Context::getTargetTexture(GLenum target) const
1260{
Ian Ewellbda75592016-04-18 17:25:54 -04001261 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001262 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001263}
1264
Geoff Lang76b10c92014-09-05 16:28:14 -04001265Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001267 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268}
1269
Geoff Lang492a7e42014-11-05 13:27:06 -05001270Compiler *Context::getCompiler() const
1271{
1272 return mCompiler;
1273}
1274
Jamie Madill893ab082014-05-16 16:56:10 -04001275void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276{
1277 switch (pname)
1278 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001279 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001280 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001282 mGLState.getBooleanv(pname, params);
1283 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001285}
1286
Jamie Madill893ab082014-05-16 16:56:10 -04001287void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001288{
Shannon Woods53a94a82014-06-24 15:20:36 -04001289 // Queries about context capabilities and maximums are answered by Context.
1290 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001291 switch (pname)
1292 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001293 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001294 params[0] = mCaps.minAliasedLineWidth;
1295 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001296 break;
1297 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001298 params[0] = mCaps.minAliasedPointSize;
1299 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001300 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001301 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001302 ASSERT(mExtensions.textureFilterAnisotropic);
1303 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001304 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001305 case GL_MAX_TEXTURE_LOD_BIAS:
1306 *params = mCaps.maxLODBias;
1307 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001308
1309 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1310 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1311 {
1312 ASSERT(mExtensions.pathRendering);
1313 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1314 memcpy(params, m, 16 * sizeof(GLfloat));
1315 }
1316 break;
1317
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001318 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001319 mGLState.getFloatv(pname, params);
1320 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001321 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322}
1323
Jamie Madill893ab082014-05-16 16:56:10 -04001324void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001325{
Shannon Woods53a94a82014-06-24 15:20:36 -04001326 // Queries about context capabilities and maximums are answered by Context.
1327 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001328
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001329 switch (pname)
1330 {
Geoff Lang301d1612014-07-09 10:34:37 -04001331 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1332 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1333 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001334 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1335 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1336 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001337 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1338 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1339 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001340 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001341 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1342 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1343 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001344 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001345 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001346 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1347 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1348 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1349 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001350 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1351 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001352 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1353 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001354 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001355 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1356 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1357 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1358 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001359 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001360 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001361 break;
1362 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001363 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001364 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001365 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1366 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001367 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1368 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1369 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001370 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1371 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1372 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001373 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001374 case GL_MAX_VIEWPORT_DIMS:
1375 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001376 params[0] = mCaps.maxViewportWidth;
1377 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001378 }
1379 break;
1380 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001381 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001382 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001383 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1384 *params = mResetStrategy;
1385 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001386 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001387 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001388 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001389 case GL_SHADER_BINARY_FORMATS:
1390 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1391 break;
1392 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001393 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001394 break;
1395 case GL_PROGRAM_BINARY_FORMATS:
1396 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001397 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001398 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001399 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001400 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001401
1402 // GL_KHR_debug
1403 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1404 *params = mExtensions.maxDebugMessageLength;
1405 break;
1406 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1407 *params = mExtensions.maxDebugLoggedMessages;
1408 break;
1409 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1410 *params = mExtensions.maxDebugGroupStackDepth;
1411 break;
1412 case GL_MAX_LABEL_LENGTH:
1413 *params = mExtensions.maxLabelLength;
1414 break;
1415
Ian Ewell53f59f42016-01-28 17:36:55 -05001416 // GL_EXT_disjoint_timer_query
1417 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001418 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001419 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001420 case GL_MAX_FRAMEBUFFER_WIDTH:
1421 *params = mCaps.maxFramebufferWidth;
1422 break;
1423 case GL_MAX_FRAMEBUFFER_HEIGHT:
1424 *params = mCaps.maxFramebufferHeight;
1425 break;
1426 case GL_MAX_FRAMEBUFFER_SAMPLES:
1427 *params = mCaps.maxFramebufferSamples;
1428 break;
1429 case GL_MAX_SAMPLE_MASK_WORDS:
1430 *params = mCaps.maxSampleMaskWords;
1431 break;
1432 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1433 *params = mCaps.maxColorTextureSamples;
1434 break;
1435 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1436 *params = mCaps.maxDepthTextureSamples;
1437 break;
1438 case GL_MAX_INTEGER_SAMPLES:
1439 *params = mCaps.maxIntegerSamples;
1440 break;
1441 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1442 *params = mCaps.maxVertexAttribRelativeOffset;
1443 break;
1444 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1445 *params = mCaps.maxVertexAttribBindings;
1446 break;
1447 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1448 *params = mCaps.maxVertexAttribStride;
1449 break;
1450 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1451 *params = mCaps.maxVertexAtomicCounterBuffers;
1452 break;
1453 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1454 *params = mCaps.maxVertexAtomicCounters;
1455 break;
1456 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1457 *params = mCaps.maxVertexImageUniforms;
1458 break;
1459 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1460 *params = mCaps.maxVertexShaderStorageBlocks;
1461 break;
1462 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1463 *params = mCaps.maxFragmentAtomicCounterBuffers;
1464 break;
1465 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1466 *params = mCaps.maxFragmentAtomicCounters;
1467 break;
1468 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1469 *params = mCaps.maxFragmentImageUniforms;
1470 break;
1471 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1472 *params = mCaps.maxFragmentShaderStorageBlocks;
1473 break;
1474 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1475 *params = mCaps.minProgramTextureGatherOffset;
1476 break;
1477 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1478 *params = mCaps.maxProgramTextureGatherOffset;
1479 break;
1480 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1481 *params = mCaps.maxComputeWorkGroupInvocations;
1482 break;
1483 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1484 *params = mCaps.maxComputeUniformBlocks;
1485 break;
1486 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1487 *params = mCaps.maxComputeTextureImageUnits;
1488 break;
1489 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1490 *params = mCaps.maxComputeSharedMemorySize;
1491 break;
1492 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1493 *params = mCaps.maxComputeUniformComponents;
1494 break;
1495 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1496 *params = mCaps.maxComputeAtomicCounterBuffers;
1497 break;
1498 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1499 *params = mCaps.maxComputeAtomicCounters;
1500 break;
1501 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1502 *params = mCaps.maxComputeImageUniforms;
1503 break;
1504 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1505 *params = mCaps.maxCombinedComputeUniformComponents;
1506 break;
1507 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1508 *params = mCaps.maxComputeShaderStorageBlocks;
1509 break;
1510 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1511 *params = mCaps.maxCombinedShaderOutputResources;
1512 break;
1513 case GL_MAX_UNIFORM_LOCATIONS:
1514 *params = mCaps.maxUniformLocations;
1515 break;
1516 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1517 *params = mCaps.maxAtomicCounterBufferBindings;
1518 break;
1519 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1520 *params = mCaps.maxAtomicCounterBufferSize;
1521 break;
1522 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1523 *params = mCaps.maxCombinedAtomicCounterBuffers;
1524 break;
1525 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1526 *params = mCaps.maxCombinedAtomicCounters;
1527 break;
1528 case GL_MAX_IMAGE_UNITS:
1529 *params = mCaps.maxImageUnits;
1530 break;
1531 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1532 *params = mCaps.maxCombinedImageUniforms;
1533 break;
1534 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1535 *params = mCaps.maxShaderStorageBufferBindings;
1536 break;
1537 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1538 *params = mCaps.maxCombinedShaderStorageBlocks;
1539 break;
1540 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1541 *params = mCaps.shaderStorageBufferOffsetAlignment;
1542 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001543 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001544 mGLState.getIntegerv(mState, pname, params);
1545 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001546 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001547}
1548
Jamie Madill893ab082014-05-16 16:56:10 -04001549void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001550{
Shannon Woods53a94a82014-06-24 15:20:36 -04001551 // Queries about context capabilities and maximums are answered by Context.
1552 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001553 switch (pname)
1554 {
1555 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001556 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001557 break;
1558 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001559 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001560 break;
1561 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001562 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001563 break;
1564 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001565 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001566 break;
1567 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001568 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001569 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001570
1571 // GL_EXT_disjoint_timer_query
1572 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001573 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001574 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001575
1576 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1577 *params = mCaps.maxShaderStorageBlockSize;
1578 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001579 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001580 UNREACHABLE();
1581 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001582 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001583}
1584
Geoff Lang70d0f492015-12-10 17:45:46 -05001585void Context::getPointerv(GLenum pname, void **params) const
1586{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001587 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001588}
1589
Martin Radev66fb8202016-07-28 11:45:20 +03001590void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001591{
Shannon Woods53a94a82014-06-24 15:20:36 -04001592 // Queries about context capabilities and maximums are answered by Context.
1593 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001594
1595 GLenum nativeType;
1596 unsigned int numParams;
1597 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1598 ASSERT(queryStatus);
1599
1600 if (nativeType == GL_INT)
1601 {
1602 switch (target)
1603 {
1604 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1605 ASSERT(index < 3u);
1606 *data = mCaps.maxComputeWorkGroupCount[index];
1607 break;
1608 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1609 ASSERT(index < 3u);
1610 *data = mCaps.maxComputeWorkGroupSize[index];
1611 break;
1612 default:
1613 mGLState.getIntegeri_v(target, index, data);
1614 }
1615 }
1616 else
1617 {
1618 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1619 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001620}
1621
Martin Radev66fb8202016-07-28 11:45:20 +03001622void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001623{
Shannon Woods53a94a82014-06-24 15:20:36 -04001624 // Queries about context capabilities and maximums are answered by Context.
1625 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001626
1627 GLenum nativeType;
1628 unsigned int numParams;
1629 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1630 ASSERT(queryStatus);
1631
1632 if (nativeType == GL_INT_64_ANGLEX)
1633 {
1634 mGLState.getInteger64i_v(target, index, data);
1635 }
1636 else
1637 {
1638 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1639 }
1640}
1641
1642void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1643{
1644 // Queries about context capabilities and maximums are answered by Context.
1645 // Queries about current GL state values are answered by State.
1646
1647 GLenum nativeType;
1648 unsigned int numParams;
1649 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1650 ASSERT(queryStatus);
1651
1652 if (nativeType == GL_BOOL)
1653 {
1654 mGLState.getBooleani_v(target, index, data);
1655 }
1656 else
1657 {
1658 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1659 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001660}
1661
He Yunchao010e4db2017-03-03 14:22:06 +08001662void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1663{
1664 Buffer *buffer = mGLState.getTargetBuffer(target);
1665 QueryBufferParameteriv(buffer, pname, params);
1666}
1667
1668void Context::getFramebufferAttachmentParameteriv(GLenum target,
1669 GLenum attachment,
1670 GLenum pname,
1671 GLint *params)
1672{
1673 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1674 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1675}
1676
1677void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1678{
1679 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1680 QueryRenderbufferiv(this, renderbuffer, pname, params);
1681}
1682
1683void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1684{
1685 Texture *texture = getTargetTexture(target);
1686 QueryTexParameterfv(texture, pname, params);
1687}
1688
1689void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1690{
1691 Texture *texture = getTargetTexture(target);
1692 QueryTexParameteriv(texture, pname, params);
1693}
1694void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1695{
1696 Texture *texture = getTargetTexture(target);
1697 SetTexParameterf(texture, pname, param);
1698}
1699
1700void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1701{
1702 Texture *texture = getTargetTexture(target);
1703 SetTexParameterfv(texture, pname, params);
1704}
1705
1706void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1707{
1708 Texture *texture = getTargetTexture(target);
1709 SetTexParameteri(texture, pname, param);
1710}
1711
1712void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1713{
1714 Texture *texture = getTargetTexture(target);
1715 SetTexParameteriv(texture, pname, params);
1716}
1717
Jamie Madill675fe712016-12-19 13:07:54 -05001718void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001719{
Jamie Madill1b94d432015-08-07 13:23:23 -04001720 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001721 auto error = mImplementation->drawArrays(mode, first, count);
1722 handleError(error);
1723 if (!error.isError())
1724 {
1725 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1726 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001727}
1728
Jamie Madill675fe712016-12-19 13:07:54 -05001729void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001730{
1731 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001732 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1733 handleError(error);
1734 if (!error.isError())
1735 {
1736 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1737 }
Geoff Langf6db0982015-08-25 13:04:00 -04001738}
1739
Jamie Madill675fe712016-12-19 13:07:54 -05001740void Context::drawElements(GLenum mode,
1741 GLsizei count,
1742 GLenum type,
1743 const GLvoid *indices,
1744 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001745{
Jamie Madill1b94d432015-08-07 13:23:23 -04001746 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001747 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001748}
1749
Jamie Madill675fe712016-12-19 13:07:54 -05001750void Context::drawElementsInstanced(GLenum mode,
1751 GLsizei count,
1752 GLenum type,
1753 const GLvoid *indices,
1754 GLsizei instances,
1755 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001756{
1757 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001758 handleError(
1759 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001760}
1761
Jamie Madill675fe712016-12-19 13:07:54 -05001762void Context::drawRangeElements(GLenum mode,
1763 GLuint start,
1764 GLuint end,
1765 GLsizei count,
1766 GLenum type,
1767 const GLvoid *indices,
1768 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001769{
1770 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001771 handleError(
1772 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001773}
1774
Jiajia Qind9671222016-11-29 16:30:31 +08001775void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1776{
1777 syncRendererState();
1778 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1779}
1780
1781void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1782{
1783 syncRendererState();
1784 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1785}
1786
Jamie Madill675fe712016-12-19 13:07:54 -05001787void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001788{
Jamie Madill675fe712016-12-19 13:07:54 -05001789 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001790}
1791
Jamie Madill675fe712016-12-19 13:07:54 -05001792void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001793{
Jamie Madill675fe712016-12-19 13:07:54 -05001794 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001795}
1796
Austin Kinross6ee1e782015-05-29 17:05:37 -07001797void Context::insertEventMarker(GLsizei length, const char *marker)
1798{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001799 ASSERT(mImplementation);
1800 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001801}
1802
1803void Context::pushGroupMarker(GLsizei length, const char *marker)
1804{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001805 ASSERT(mImplementation);
1806 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001807}
1808
1809void Context::popGroupMarker()
1810{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001811 ASSERT(mImplementation);
1812 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001813}
1814
Geoff Langd8605522016-04-13 10:19:12 -04001815void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1816{
1817 Program *programObject = getProgram(program);
1818 ASSERT(programObject);
1819
1820 programObject->bindUniformLocation(location, name);
1821}
1822
Sami Väisänena797e062016-05-12 15:23:40 +03001823void Context::setCoverageModulation(GLenum components)
1824{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001825 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001826}
1827
Sami Väisänene45e53b2016-05-25 10:36:04 +03001828void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1829{
1830 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1831}
1832
1833void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1834{
1835 GLfloat I[16];
1836 angle::Matrix<GLfloat>::setToIdentity(I);
1837
1838 mGLState.loadPathRenderingMatrix(matrixMode, I);
1839}
1840
1841void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1842{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001843 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001844 if (!pathObj)
1845 return;
1846
1847 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1848 syncRendererState();
1849
1850 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1851}
1852
1853void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1854{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001855 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001856 if (!pathObj)
1857 return;
1858
1859 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1860 syncRendererState();
1861
1862 mImplementation->stencilStrokePath(pathObj, reference, mask);
1863}
1864
1865void Context::coverFillPath(GLuint path, GLenum coverMode)
1866{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001867 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001868 if (!pathObj)
1869 return;
1870
1871 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1872 syncRendererState();
1873
1874 mImplementation->coverFillPath(pathObj, coverMode);
1875}
1876
1877void Context::coverStrokePath(GLuint path, GLenum coverMode)
1878{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001879 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001880 if (!pathObj)
1881 return;
1882
1883 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1884 syncRendererState();
1885
1886 mImplementation->coverStrokePath(pathObj, coverMode);
1887}
1888
1889void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1890{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001891 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001892 if (!pathObj)
1893 return;
1894
1895 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1896 syncRendererState();
1897
1898 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1899}
1900
1901void Context::stencilThenCoverStrokePath(GLuint path,
1902 GLint reference,
1903 GLuint mask,
1904 GLenum coverMode)
1905{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001906 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001907 if (!pathObj)
1908 return;
1909
1910 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1911 syncRendererState();
1912
1913 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1914}
1915
Sami Väisänend59ca052016-06-21 16:10:00 +03001916void Context::coverFillPathInstanced(GLsizei numPaths,
1917 GLenum pathNameType,
1918 const void *paths,
1919 GLuint pathBase,
1920 GLenum coverMode,
1921 GLenum transformType,
1922 const GLfloat *transformValues)
1923{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001924 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001925
1926 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1927 syncRendererState();
1928
1929 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1930}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001931
Sami Väisänend59ca052016-06-21 16:10:00 +03001932void Context::coverStrokePathInstanced(GLsizei numPaths,
1933 GLenum pathNameType,
1934 const void *paths,
1935 GLuint pathBase,
1936 GLenum coverMode,
1937 GLenum transformType,
1938 const GLfloat *transformValues)
1939{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001940 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001941
1942 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1943 syncRendererState();
1944
1945 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1946 transformValues);
1947}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001948
Sami Väisänend59ca052016-06-21 16:10:00 +03001949void Context::stencilFillPathInstanced(GLsizei numPaths,
1950 GLenum pathNameType,
1951 const void *paths,
1952 GLuint pathBase,
1953 GLenum fillMode,
1954 GLuint mask,
1955 GLenum transformType,
1956 const GLfloat *transformValues)
1957{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001958 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001959
1960 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1961 syncRendererState();
1962
1963 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1964 transformValues);
1965}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001966
Sami Väisänend59ca052016-06-21 16:10:00 +03001967void Context::stencilStrokePathInstanced(GLsizei numPaths,
1968 GLenum pathNameType,
1969 const void *paths,
1970 GLuint pathBase,
1971 GLint reference,
1972 GLuint mask,
1973 GLenum transformType,
1974 const GLfloat *transformValues)
1975{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001976 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001977
1978 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1979 syncRendererState();
1980
1981 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1982 transformValues);
1983}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001984
Sami Väisänend59ca052016-06-21 16:10:00 +03001985void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1986 GLenum pathNameType,
1987 const void *paths,
1988 GLuint pathBase,
1989 GLenum fillMode,
1990 GLuint mask,
1991 GLenum coverMode,
1992 GLenum transformType,
1993 const GLfloat *transformValues)
1994{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001995 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001996
1997 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1998 syncRendererState();
1999
2000 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2001 transformType, transformValues);
2002}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002003
Sami Väisänend59ca052016-06-21 16:10:00 +03002004void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2005 GLenum pathNameType,
2006 const void *paths,
2007 GLuint pathBase,
2008 GLint reference,
2009 GLuint mask,
2010 GLenum coverMode,
2011 GLenum transformType,
2012 const GLfloat *transformValues)
2013{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002014 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002015
2016 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2017 syncRendererState();
2018
2019 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2020 transformType, transformValues);
2021}
2022
Sami Väisänen46eaa942016-06-29 10:26:37 +03002023void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2024{
2025 auto *programObject = getProgram(program);
2026
2027 programObject->bindFragmentInputLocation(location, name);
2028}
2029
2030void Context::programPathFragmentInputGen(GLuint program,
2031 GLint location,
2032 GLenum genMode,
2033 GLint components,
2034 const GLfloat *coeffs)
2035{
2036 auto *programObject = getProgram(program);
2037
2038 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
2039}
2040
jchen1015015f72017-03-16 13:54:21 +08002041GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2042{
2043 gl::Program *programObject = getProgram(program);
2044 return QueryProgramResourceIndex(programObject, programInterface, name);
2045}
2046
Jamie Madill437fa652016-05-03 15:13:24 -04002047void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002048{
Geoff Langda5777c2014-07-11 09:52:58 -04002049 if (error.isError())
2050 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002051 GLenum code = error.getCode();
2052 mErrors.insert(code);
2053 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2054 {
2055 markContextLost();
2056 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002057
2058 if (!error.getMessage().empty())
2059 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002060 auto *debug = &mGLState.getDebug();
2061 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2062 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002063 }
Geoff Langda5777c2014-07-11 09:52:58 -04002064 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002065}
2066
2067// Get one of the recorded errors and clear its flag, if any.
2068// [OpenGL ES 2.0.24] section 2.5 page 13.
2069GLenum Context::getError()
2070{
Geoff Langda5777c2014-07-11 09:52:58 -04002071 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002072 {
Geoff Langda5777c2014-07-11 09:52:58 -04002073 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002074 }
Geoff Langda5777c2014-07-11 09:52:58 -04002075 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002076 {
Geoff Langda5777c2014-07-11 09:52:58 -04002077 GLenum error = *mErrors.begin();
2078 mErrors.erase(mErrors.begin());
2079 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002080 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002081}
2082
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002083// NOTE: this function should not assume that this context is current!
2084void Context::markContextLost()
2085{
2086 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002087 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002088 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002089 mContextLostForced = true;
2090 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002091 mContextLost = true;
2092}
2093
2094bool Context::isContextLost()
2095{
2096 return mContextLost;
2097}
2098
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002099GLenum Context::getResetStatus()
2100{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002101 // Even if the application doesn't want to know about resets, we want to know
2102 // as it will allow us to skip all the calls.
2103 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002104 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002105 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002106 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002107 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002108 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002109
2110 // EXT_robustness, section 2.6: If the reset notification behavior is
2111 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2112 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2113 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002114 }
2115
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002116 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2117 // status should be returned at least once, and GL_NO_ERROR should be returned
2118 // once the device has finished resetting.
2119 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002120 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002121 ASSERT(mResetStatus == GL_NO_ERROR);
2122 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002123
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002124 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002125 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002126 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002127 }
2128 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002129 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002130 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002131 // If markContextLost was used to mark the context lost then
2132 // assume that is not recoverable, and continue to report the
2133 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002134 mResetStatus = mImplementation->getResetStatus();
2135 }
Jamie Madill893ab082014-05-16 16:56:10 -04002136
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002137 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002138}
2139
2140bool Context::isResetNotificationEnabled()
2141{
2142 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2143}
2144
Corentin Walleze3b10e82015-05-20 11:06:25 -04002145const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002146{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002147 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002148}
2149
2150EGLenum Context::getClientType() const
2151{
2152 return mClientType;
2153}
2154
2155EGLenum Context::getRenderBuffer() const
2156{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002157 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2158 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002159 {
2160 return EGL_NONE;
2161 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002162
2163 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2164 ASSERT(backAttachment != nullptr);
2165 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002166}
2167
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002168VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002169{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002170 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002171 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2172 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002173 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002174 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2175 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002176
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002177 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002178 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002179
2180 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002181}
2182
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002183TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002184{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002185 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002186 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2187 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002188 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002189 transformFeedback =
2190 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002191 transformFeedback->addRef();
2192 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002193 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002194
2195 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002196}
2197
2198bool Context::isVertexArrayGenerated(GLuint vertexArray)
2199{
Geoff Langf41a7152016-09-19 15:11:17 -04002200 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002201 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2202}
2203
2204bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2205{
Geoff Langf41a7152016-09-19 15:11:17 -04002206 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002207 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2208}
2209
Shannon Woods53a94a82014-06-24 15:20:36 -04002210void Context::detachTexture(GLuint texture)
2211{
2212 // Simple pass-through to State's detachTexture method, as textures do not require
2213 // allocation map management either here or in the resource manager at detach time.
2214 // Zero textures are held by the Context, and we don't attempt to request them from
2215 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002216 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002217}
2218
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002219void Context::detachBuffer(GLuint buffer)
2220{
Yuly Novikov5807a532015-12-03 13:01:22 -05002221 // Simple pass-through to State's detachBuffer method, since
2222 // only buffer attachments to container objects that are bound to the current context
2223 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002224
Yuly Novikov5807a532015-12-03 13:01:22 -05002225 // [OpenGL ES 3.2] section 5.1.2 page 45:
2226 // Attachments to unbound container objects, such as
2227 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2228 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002229 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002230}
2231
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002232void Context::detachFramebuffer(GLuint framebuffer)
2233{
Shannon Woods53a94a82014-06-24 15:20:36 -04002234 // Framebuffer detachment is handled by Context, because 0 is a valid
2235 // Framebuffer object, and a pointer to it must be passed from Context
2236 // to State at binding time.
2237
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002238 // [OpenGL ES 2.0.24] section 4.4 page 107:
2239 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2240 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2241
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002242 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002243 {
2244 bindReadFramebuffer(0);
2245 }
2246
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002247 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002248 {
2249 bindDrawFramebuffer(0);
2250 }
2251}
2252
2253void Context::detachRenderbuffer(GLuint renderbuffer)
2254{
Jamie Madilla02315b2017-02-23 14:14:47 -05002255 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002256}
2257
Jamie Madill57a89722013-07-02 11:57:03 -04002258void Context::detachVertexArray(GLuint vertexArray)
2259{
Jamie Madill77a72f62015-04-14 11:18:32 -04002260 // Vertex array detachment is handled by Context, because 0 is a valid
2261 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002262 // binding time.
2263
Jamie Madill57a89722013-07-02 11:57:03 -04002264 // [OpenGL ES 3.0.2] section 2.10 page 43:
2265 // If a vertex array object that is currently bound is deleted, the binding
2266 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002267 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002268 {
2269 bindVertexArray(0);
2270 }
2271}
2272
Geoff Langc8058452014-02-03 12:04:11 -05002273void Context::detachTransformFeedback(GLuint transformFeedback)
2274{
Corentin Walleza2257da2016-04-19 16:43:12 -04002275 // Transform feedback detachment is handled by Context, because 0 is a valid
2276 // transform feedback, and a pointer to it must be passed from Context to State at
2277 // binding time.
2278
2279 // The OpenGL specification doesn't mention what should happen when the currently bound
2280 // transform feedback object is deleted. Since it is a container object, we treat it like
2281 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002282 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002283 {
2284 bindTransformFeedback(0);
2285 }
Geoff Langc8058452014-02-03 12:04:11 -05002286}
2287
Jamie Madilldc356042013-07-19 16:36:57 -04002288void Context::detachSampler(GLuint sampler)
2289{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002290 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002291}
2292
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002293void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2294{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002295 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002296}
2297
Jamie Madille29d1672013-07-19 16:36:57 -04002298void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2299{
Geoff Langc1984ed2016-10-07 12:41:00 -04002300 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002301 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002302 SetSamplerParameteri(samplerObject, pname, param);
2303}
Jamie Madille29d1672013-07-19 16:36:57 -04002304
Geoff Langc1984ed2016-10-07 12:41:00 -04002305void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2306{
2307 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002308 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002309 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002310}
2311
2312void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2313{
Geoff Langc1984ed2016-10-07 12:41:00 -04002314 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002315 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002316 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002317}
2318
Geoff Langc1984ed2016-10-07 12:41:00 -04002319void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002320{
Geoff Langc1984ed2016-10-07 12:41:00 -04002321 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002322 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002323 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002324}
2325
Geoff Langc1984ed2016-10-07 12:41:00 -04002326void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002327{
Geoff Langc1984ed2016-10-07 12:41:00 -04002328 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002329 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002330 QuerySamplerParameteriv(samplerObject, pname, params);
2331}
Jamie Madill9675b802013-07-19 16:36:59 -04002332
Geoff Langc1984ed2016-10-07 12:41:00 -04002333void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2334{
2335 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002336 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002337 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002338}
2339
Olli Etuahof0fee072016-03-30 15:11:58 +03002340void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2341{
2342 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002343 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002344}
2345
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002346void Context::initRendererString()
2347{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002348 std::ostringstream rendererString;
2349 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002350 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002351 rendererString << ")";
2352
Geoff Langcec35902014-04-16 10:52:36 -04002353 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002354}
2355
Geoff Langc339c4e2016-11-29 10:37:36 -05002356void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002357{
Geoff Langc339c4e2016-11-29 10:37:36 -05002358 const Version &clientVersion = getClientVersion();
2359
2360 std::ostringstream versionString;
2361 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2362 << ANGLE_VERSION_STRING << ")";
2363 mVersionString = MakeStaticString(versionString.str());
2364
2365 std::ostringstream shadingLanguageVersionString;
2366 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2367 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2368 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2369 << ")";
2370 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002371}
2372
Geoff Langcec35902014-04-16 10:52:36 -04002373void Context::initExtensionStrings()
2374{
Geoff Langc339c4e2016-11-29 10:37:36 -05002375 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2376 std::ostringstream combinedStringStream;
2377 std::copy(strings.begin(), strings.end(),
2378 std::ostream_iterator<const char *>(combinedStringStream, " "));
2379 return MakeStaticString(combinedStringStream.str());
2380 };
2381
2382 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002383 for (const auto &extensionString : mExtensions.getStrings())
2384 {
2385 mExtensionStrings.push_back(MakeStaticString(extensionString));
2386 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002387 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002388
Bryan Bernhart58806562017-01-05 13:09:31 -08002389 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2390
Geoff Langc339c4e2016-11-29 10:37:36 -05002391 mRequestableExtensionStrings.clear();
2392 for (const auto &extensionInfo : GetExtensionInfoMap())
2393 {
2394 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002395 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2396 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002397 {
2398 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2399 }
2400 }
2401 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002402}
2403
Geoff Langc339c4e2016-11-29 10:37:36 -05002404const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002405{
Geoff Langc339c4e2016-11-29 10:37:36 -05002406 switch (name)
2407 {
2408 case GL_VENDOR:
2409 return reinterpret_cast<const GLubyte *>("Google Inc.");
2410
2411 case GL_RENDERER:
2412 return reinterpret_cast<const GLubyte *>(mRendererString);
2413
2414 case GL_VERSION:
2415 return reinterpret_cast<const GLubyte *>(mVersionString);
2416
2417 case GL_SHADING_LANGUAGE_VERSION:
2418 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2419
2420 case GL_EXTENSIONS:
2421 return reinterpret_cast<const GLubyte *>(mExtensionString);
2422
2423 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2424 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2425
2426 default:
2427 UNREACHABLE();
2428 return nullptr;
2429 }
Geoff Langcec35902014-04-16 10:52:36 -04002430}
2431
Geoff Langc339c4e2016-11-29 10:37:36 -05002432const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002433{
Geoff Langc339c4e2016-11-29 10:37:36 -05002434 switch (name)
2435 {
2436 case GL_EXTENSIONS:
2437 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2438
2439 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2440 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2441
2442 default:
2443 UNREACHABLE();
2444 return nullptr;
2445 }
Geoff Langcec35902014-04-16 10:52:36 -04002446}
2447
2448size_t Context::getExtensionStringCount() const
2449{
2450 return mExtensionStrings.size();
2451}
2452
Geoff Langc339c4e2016-11-29 10:37:36 -05002453void Context::requestExtension(const char *name)
2454{
2455 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2456 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2457 const auto &extension = extensionInfos.at(name);
2458 ASSERT(extension.Requestable);
2459
2460 if (mExtensions.*(extension.ExtensionsMember))
2461 {
2462 // Extension already enabled
2463 return;
2464 }
2465
2466 mExtensions.*(extension.ExtensionsMember) = true;
2467 updateCaps();
2468 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002469
2470 // Re-create the compiler with the requested extensions enabled.
2471 SafeDelete(mCompiler);
2472 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002473}
2474
2475size_t Context::getRequestableExtensionStringCount() const
2476{
2477 return mRequestableExtensionStrings.size();
2478}
2479
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002480void Context::beginTransformFeedback(GLenum primitiveMode)
2481{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002482 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002483 ASSERT(transformFeedback != nullptr);
2484 ASSERT(!transformFeedback->isPaused());
2485
Jamie Madill6c1f6712017-02-14 19:08:04 -05002486 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002487}
2488
2489bool Context::hasActiveTransformFeedback(GLuint program) const
2490{
2491 for (auto pair : mTransformFeedbackMap)
2492 {
2493 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2494 {
2495 return true;
2496 }
2497 }
2498 return false;
2499}
2500
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002501void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002502{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002503 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002504
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002505 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002506
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002507 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002508
Geoff Langeb66a6e2016-10-31 13:06:12 -04002509 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002510 {
2511 // Disable ES3+ extensions
2512 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002513 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002514 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002515 }
2516
Geoff Langeb66a6e2016-10-31 13:06:12 -04002517 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002518 {
2519 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2520 //mExtensions.sRGB = false;
2521 }
2522
Jamie Madill00ed7a12016-05-19 13:13:38 -04002523 // Some extensions are always available because they are implemented in the GL layer.
2524 mExtensions.bindUniformLocation = true;
2525 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002526 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002527 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002528 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002529
2530 // Enable the no error extension if the context was created with the flag.
2531 mExtensions.noError = mSkipValidation;
2532
Corentin Wallezccab69d2017-01-27 16:57:15 -05002533 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002534 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002535
Geoff Lang70d0f492015-12-10 17:45:46 -05002536 // Explicitly enable GL_KHR_debug
2537 mExtensions.debug = true;
2538 mExtensions.maxDebugMessageLength = 1024;
2539 mExtensions.maxDebugLoggedMessages = 1024;
2540 mExtensions.maxDebugGroupStackDepth = 1024;
2541 mExtensions.maxLabelLength = 1024;
2542
Geoff Langff5b2d52016-09-07 11:32:23 -04002543 // Explicitly enable GL_ANGLE_robust_client_memory
2544 mExtensions.robustClientMemory = true;
2545
Jamie Madille08a1d32017-03-07 17:24:06 -05002546 // Determine robust resource init availability from EGL.
2547 mExtensions.robustResourceInitialization =
2548 displayExtensions.createContextRobustResourceInitialization;
2549
Geoff Lang301d1612014-07-09 10:34:37 -04002550 // Apply implementation limits
2551 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002552 mCaps.maxVertexAttribBindings =
2553 getClientVersion() < ES_3_1
2554 ? mCaps.maxVertexAttributes
2555 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2556
Geoff Lang301d1612014-07-09 10:34:37 -04002557 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2558 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2559
2560 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002561
Geoff Langc287ea62016-09-16 14:46:51 -04002562 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002563 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002564 for (const auto &extensionInfo : GetExtensionInfoMap())
2565 {
2566 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002567 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002568 {
2569 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2570 }
2571 }
2572
2573 // Generate texture caps
2574 updateCaps();
2575}
2576
2577void Context::updateCaps()
2578{
Geoff Lang900013c2014-07-07 11:32:19 -04002579 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002580 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002581
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002582 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002583 {
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002584 GLenum format = capsIt.first;
2585 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002586
Geoff Lang5d601382014-07-22 15:14:06 -04002587 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002588
Geoff Lang0d8b7242015-09-09 14:56:53 -04002589 // Update the format caps based on the client version and extensions.
2590 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2591 // ES3.
2592 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002593 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002594 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002595 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002596 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002597 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002598
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002599 // OpenGL ES does not support multisampling with non-rendererable formats
2600 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2601 if (!formatInfo.renderSupport ||
2602 (getClientVersion() < ES_3_1 &&
2603 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002604 {
Geoff Langd87878e2014-09-19 15:42:59 -04002605 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002606 }
Geoff Langd87878e2014-09-19 15:42:59 -04002607
2608 if (formatCaps.texturable && formatInfo.compressed)
2609 {
2610 mCaps.compressedTextureFormats.push_back(format);
2611 }
2612
2613 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002614 }
2615}
2616
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002617void Context::initWorkarounds()
2618{
2619 // Lose the context upon out of memory error if the application is
2620 // expecting to watch for those events.
2621 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2622}
2623
Jamie Madill1b94d432015-08-07 13:23:23 -04002624void Context::syncRendererState()
2625{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002626 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002627 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002628 mGLState.clearDirtyBits();
2629 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002630}
2631
Jamie Madillad9f24e2016-02-12 09:27:24 -05002632void Context::syncRendererState(const State::DirtyBits &bitMask,
2633 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002634{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002635 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002636 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002637 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002638
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002639 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002640}
Jamie Madillc29968b2016-01-20 11:17:23 -05002641
2642void Context::blitFramebuffer(GLint srcX0,
2643 GLint srcY0,
2644 GLint srcX1,
2645 GLint srcY1,
2646 GLint dstX0,
2647 GLint dstY0,
2648 GLint dstX1,
2649 GLint dstY1,
2650 GLbitfield mask,
2651 GLenum filter)
2652{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002653 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002654 ASSERT(drawFramebuffer);
2655
2656 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2657 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2658
Jamie Madillad9f24e2016-02-12 09:27:24 -05002659 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002660
Jamie Madill8415b5f2016-04-26 13:41:39 -04002661 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002662}
Jamie Madillc29968b2016-01-20 11:17:23 -05002663
2664void Context::clear(GLbitfield mask)
2665{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002666 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002667 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002668}
2669
2670void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2671{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002672 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002673 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2674 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002675}
2676
2677void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2678{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002679 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002680 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2681 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002682}
2683
2684void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2685{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002686 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002687 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2688 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002689}
2690
2691void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2692{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002693 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002694 ASSERT(framebufferObject);
2695
2696 // If a buffer is not present, the clear has no effect
2697 if (framebufferObject->getDepthbuffer() == nullptr &&
2698 framebufferObject->getStencilbuffer() == nullptr)
2699 {
2700 return;
2701 }
2702
Jamie Madillad9f24e2016-02-12 09:27:24 -05002703 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002704 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2705 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002706}
2707
2708void Context::readPixels(GLint x,
2709 GLint y,
2710 GLsizei width,
2711 GLsizei height,
2712 GLenum format,
2713 GLenum type,
2714 GLvoid *pixels)
2715{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002716 if (width == 0 || height == 0)
2717 {
2718 return;
2719 }
2720
Jamie Madillad9f24e2016-02-12 09:27:24 -05002721 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002722
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002723 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002724 ASSERT(framebufferObject);
2725
2726 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002727 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002728}
2729
2730void Context::copyTexImage2D(GLenum target,
2731 GLint level,
2732 GLenum internalformat,
2733 GLint x,
2734 GLint y,
2735 GLsizei width,
2736 GLsizei height,
2737 GLint border)
2738{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002739 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002740 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002741
Jamie Madillc29968b2016-01-20 11:17:23 -05002742 Rectangle sourceArea(x, y, width, height);
2743
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002744 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002745 Texture *texture =
2746 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002747 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002748}
2749
2750void Context::copyTexSubImage2D(GLenum target,
2751 GLint level,
2752 GLint xoffset,
2753 GLint yoffset,
2754 GLint x,
2755 GLint y,
2756 GLsizei width,
2757 GLsizei height)
2758{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002759 if (width == 0 || height == 0)
2760 {
2761 return;
2762 }
2763
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002764 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002765 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002766
Jamie Madillc29968b2016-01-20 11:17:23 -05002767 Offset destOffset(xoffset, yoffset, 0);
2768 Rectangle sourceArea(x, y, width, height);
2769
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002770 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002771 Texture *texture =
2772 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002773 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002774}
2775
2776void Context::copyTexSubImage3D(GLenum target,
2777 GLint level,
2778 GLint xoffset,
2779 GLint yoffset,
2780 GLint zoffset,
2781 GLint x,
2782 GLint y,
2783 GLsizei width,
2784 GLsizei height)
2785{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002786 if (width == 0 || height == 0)
2787 {
2788 return;
2789 }
2790
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002791 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002792 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002793
Jamie Madillc29968b2016-01-20 11:17:23 -05002794 Offset destOffset(xoffset, yoffset, zoffset);
2795 Rectangle sourceArea(x, y, width, height);
2796
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002797 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002798 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002799 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002800}
2801
2802void Context::framebufferTexture2D(GLenum target,
2803 GLenum attachment,
2804 GLenum textarget,
2805 GLuint texture,
2806 GLint level)
2807{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002808 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002809 ASSERT(framebuffer);
2810
2811 if (texture != 0)
2812 {
2813 Texture *textureObj = getTexture(texture);
2814
2815 ImageIndex index = ImageIndex::MakeInvalid();
2816
2817 if (textarget == GL_TEXTURE_2D)
2818 {
2819 index = ImageIndex::Make2D(level);
2820 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002821 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2822 {
2823 ASSERT(level == 0);
2824 index = ImageIndex::Make2DMultisample();
2825 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002826 else
2827 {
2828 ASSERT(IsCubeMapTextureTarget(textarget));
2829 index = ImageIndex::MakeCube(textarget, level);
2830 }
2831
Jamie Madilla02315b2017-02-23 14:14:47 -05002832 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002833 }
2834 else
2835 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002836 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002837 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002838
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002839 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002840}
2841
2842void Context::framebufferRenderbuffer(GLenum target,
2843 GLenum attachment,
2844 GLenum renderbuffertarget,
2845 GLuint renderbuffer)
2846{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002847 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002848 ASSERT(framebuffer);
2849
2850 if (renderbuffer != 0)
2851 {
2852 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002853
2854 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002855 renderbufferObject);
2856 }
2857 else
2858 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002859 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002860 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002861
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002862 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002863}
2864
2865void Context::framebufferTextureLayer(GLenum target,
2866 GLenum attachment,
2867 GLuint texture,
2868 GLint level,
2869 GLint layer)
2870{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002871 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002872 ASSERT(framebuffer);
2873
2874 if (texture != 0)
2875 {
2876 Texture *textureObject = getTexture(texture);
2877
2878 ImageIndex index = ImageIndex::MakeInvalid();
2879
2880 if (textureObject->getTarget() == GL_TEXTURE_3D)
2881 {
2882 index = ImageIndex::Make3D(level, layer);
2883 }
2884 else
2885 {
2886 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2887 index = ImageIndex::Make2DArray(level, layer);
2888 }
2889
Jamie Madilla02315b2017-02-23 14:14:47 -05002890 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05002891 }
2892 else
2893 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002894 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002895 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002896
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002897 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002898}
2899
2900void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2901{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002902 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002903 ASSERT(framebuffer);
2904 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002905 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002906}
2907
2908void Context::readBuffer(GLenum mode)
2909{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002910 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002911 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002912 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002913}
2914
2915void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2916{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002917 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002918 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002919
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002920 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002921 ASSERT(framebuffer);
2922
2923 // The specification isn't clear what should be done when the framebuffer isn't complete.
2924 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002925 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002926}
2927
2928void Context::invalidateFramebuffer(GLenum target,
2929 GLsizei numAttachments,
2930 const GLenum *attachments)
2931{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002932 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002933 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002934
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002935 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002936 ASSERT(framebuffer);
2937
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002938 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002939 {
Jamie Madill437fa652016-05-03 15:13:24 -04002940 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002941 }
Jamie Madill437fa652016-05-03 15:13:24 -04002942
2943 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002944}
2945
2946void Context::invalidateSubFramebuffer(GLenum target,
2947 GLsizei numAttachments,
2948 const GLenum *attachments,
2949 GLint x,
2950 GLint y,
2951 GLsizei width,
2952 GLsizei height)
2953{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002954 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002955 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002956
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002957 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002958 ASSERT(framebuffer);
2959
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002960 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002961 {
Jamie Madill437fa652016-05-03 15:13:24 -04002962 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002963 }
Jamie Madill437fa652016-05-03 15:13:24 -04002964
2965 Rectangle area(x, y, width, height);
2966 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002967}
2968
Jamie Madill73a84962016-02-12 09:27:23 -05002969void Context::texImage2D(GLenum target,
2970 GLint level,
2971 GLint internalformat,
2972 GLsizei width,
2973 GLsizei height,
2974 GLint border,
2975 GLenum format,
2976 GLenum type,
2977 const GLvoid *pixels)
2978{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002979 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002980
2981 Extents size(width, height, 1);
2982 Texture *texture =
2983 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002984 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2985 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002986}
2987
2988void Context::texImage3D(GLenum target,
2989 GLint level,
2990 GLint internalformat,
2991 GLsizei width,
2992 GLsizei height,
2993 GLsizei depth,
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, depth);
3002 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003003 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3004 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003005}
3006
3007void Context::texSubImage2D(GLenum target,
3008 GLint level,
3009 GLint xoffset,
3010 GLint yoffset,
3011 GLsizei width,
3012 GLsizei height,
3013 GLenum format,
3014 GLenum type,
3015 const GLvoid *pixels)
3016{
3017 // Zero sized uploads are valid but no-ops
3018 if (width == 0 || height == 0)
3019 {
3020 return;
3021 }
3022
Jamie Madillad9f24e2016-02-12 09:27:24 -05003023 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003024
3025 Box area(xoffset, yoffset, 0, width, height, 1);
3026 Texture *texture =
3027 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003028 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3029 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003030}
3031
3032void Context::texSubImage3D(GLenum target,
3033 GLint level,
3034 GLint xoffset,
3035 GLint yoffset,
3036 GLint zoffset,
3037 GLsizei width,
3038 GLsizei height,
3039 GLsizei depth,
3040 GLenum format,
3041 GLenum type,
3042 const GLvoid *pixels)
3043{
3044 // Zero sized uploads are valid but no-ops
3045 if (width == 0 || height == 0 || depth == 0)
3046 {
3047 return;
3048 }
3049
Jamie Madillad9f24e2016-02-12 09:27:24 -05003050 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003051
3052 Box area(xoffset, yoffset, zoffset, width, height, depth);
3053 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003054 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3055 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003056}
3057
3058void Context::compressedTexImage2D(GLenum target,
3059 GLint level,
3060 GLenum internalformat,
3061 GLsizei width,
3062 GLsizei height,
3063 GLint border,
3064 GLsizei imageSize,
3065 const GLvoid *data)
3066{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003067 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003068
3069 Extents size(width, height, 1);
3070 Texture *texture =
3071 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003072 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003073 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003074 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003075}
3076
3077void Context::compressedTexImage3D(GLenum target,
3078 GLint level,
3079 GLenum internalformat,
3080 GLsizei width,
3081 GLsizei height,
3082 GLsizei depth,
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, depth);
3090 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003091 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003092 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003093 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003094}
3095
3096void Context::compressedTexSubImage2D(GLenum target,
3097 GLint level,
3098 GLint xoffset,
3099 GLint yoffset,
3100 GLsizei width,
3101 GLsizei height,
3102 GLenum format,
3103 GLsizei imageSize,
3104 const GLvoid *data)
3105{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003106 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003107
3108 Box area(xoffset, yoffset, 0, width, height, 1);
3109 Texture *texture =
3110 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003111 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003112 format, imageSize,
3113 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003114}
3115
3116void Context::compressedTexSubImage3D(GLenum target,
3117 GLint level,
3118 GLint xoffset,
3119 GLint yoffset,
3120 GLint zoffset,
3121 GLsizei width,
3122 GLsizei height,
3123 GLsizei depth,
3124 GLenum format,
3125 GLsizei imageSize,
3126 const GLvoid *data)
3127{
3128 // Zero sized uploads are valid but no-ops
3129 if (width == 0 || height == 0)
3130 {
3131 return;
3132 }
3133
Jamie Madillad9f24e2016-02-12 09:27:24 -05003134 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003135
3136 Box area(xoffset, yoffset, zoffset, width, height, depth);
3137 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003138 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003139 format, imageSize,
3140 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003141}
3142
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003143void Context::generateMipmap(GLenum target)
3144{
3145 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003146 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003147}
3148
Geoff Lang97073d12016-04-20 10:42:34 -07003149void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003150 GLint sourceLevel,
3151 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003152 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003153 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003154 GLint internalFormat,
3155 GLenum destType,
3156 GLboolean unpackFlipY,
3157 GLboolean unpackPremultiplyAlpha,
3158 GLboolean unpackUnmultiplyAlpha)
3159{
3160 syncStateForTexImage();
3161
3162 gl::Texture *sourceTexture = getTexture(sourceId);
3163 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003164 handleError(destTexture->copyTexture(
3165 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3166 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003167}
3168
3169void Context::copySubTextureCHROMIUM(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 xoffset,
3175 GLint yoffset,
3176 GLint x,
3177 GLint y,
3178 GLsizei width,
3179 GLsizei height,
3180 GLboolean unpackFlipY,
3181 GLboolean unpackPremultiplyAlpha,
3182 GLboolean unpackUnmultiplyAlpha)
3183{
3184 // Zero sized copies are valid but no-ops
3185 if (width == 0 || height == 0)
3186 {
3187 return;
3188 }
3189
3190 syncStateForTexImage();
3191
3192 gl::Texture *sourceTexture = getTexture(sourceId);
3193 gl::Texture *destTexture = getTexture(destId);
3194 Offset offset(xoffset, yoffset, 0);
3195 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003196 handleError(destTexture->copySubTexture(
3197 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3198 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003199}
3200
Geoff Lang47110bf2016-04-20 11:13:22 -07003201void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3202{
3203 syncStateForTexImage();
3204
3205 gl::Texture *sourceTexture = getTexture(sourceId);
3206 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003207 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003208}
3209
Geoff Lang496c02d2016-10-20 11:38:11 -07003210void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003212 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003213 ASSERT(buffer);
3214
Geoff Lang496c02d2016-10-20 11:38:11 -07003215 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003216}
3217
3218GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3219{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003220 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003221 ASSERT(buffer);
3222
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003223 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003224 if (error.isError())
3225 {
Jamie Madill437fa652016-05-03 15:13:24 -04003226 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003227 return nullptr;
3228 }
3229
3230 return buffer->getMapPointer();
3231}
3232
3233GLboolean Context::unmapBuffer(GLenum target)
3234{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003235 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003236 ASSERT(buffer);
3237
3238 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003239 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003240 if (error.isError())
3241 {
Jamie Madill437fa652016-05-03 15:13:24 -04003242 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003243 return GL_FALSE;
3244 }
3245
3246 return result;
3247}
3248
3249GLvoid *Context::mapBufferRange(GLenum target,
3250 GLintptr offset,
3251 GLsizeiptr length,
3252 GLbitfield access)
3253{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003254 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003255 ASSERT(buffer);
3256
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003257 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003258 if (error.isError())
3259 {
Jamie Madill437fa652016-05-03 15:13:24 -04003260 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003261 return nullptr;
3262 }
3263
3264 return buffer->getMapPointer();
3265}
3266
3267void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3268{
3269 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3270}
3271
Jamie Madillad9f24e2016-02-12 09:27:24 -05003272void Context::syncStateForReadPixels()
3273{
3274 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3275}
3276
3277void Context::syncStateForTexImage()
3278{
3279 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3280}
3281
3282void Context::syncStateForClear()
3283{
3284 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3285}
3286
3287void Context::syncStateForBlit()
3288{
3289 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3290}
3291
Jamie Madillc20ab272016-06-09 07:20:46 -07003292void Context::activeTexture(GLenum texture)
3293{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003294 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003295}
3296
3297void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3298{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003299 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003300}
3301
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003302void Context::blendEquation(GLenum mode)
3303{
3304 mGLState.setBlendEquation(mode, mode);
3305}
3306
Jamie Madillc20ab272016-06-09 07:20:46 -07003307void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3308{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003309 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003310}
3311
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003312void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3313{
3314 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3315}
3316
Jamie Madillc20ab272016-06-09 07:20:46 -07003317void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3318{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003319 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003320}
3321
3322void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3323{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003324 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003325}
3326
3327void Context::clearDepthf(GLclampf depth)
3328{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003329 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003330}
3331
3332void Context::clearStencil(GLint s)
3333{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335}
3336
3337void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3338{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340}
3341
3342void Context::cullFace(GLenum mode)
3343{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345}
3346
3347void Context::depthFunc(GLenum func)
3348{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003350}
3351
3352void Context::depthMask(GLboolean flag)
3353{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003355}
3356
3357void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3358{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003359 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003360}
3361
3362void Context::disable(GLenum cap)
3363{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365}
3366
3367void Context::disableVertexAttribArray(GLuint index)
3368{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370}
3371
3372void Context::enable(GLenum cap)
3373{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003374 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003375}
3376
3377void Context::enableVertexAttribArray(GLuint index)
3378{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003379 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003380}
3381
3382void Context::frontFace(GLenum mode)
3383{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003384 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003385}
3386
3387void Context::hint(GLenum target, GLenum mode)
3388{
3389 switch (target)
3390 {
3391 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003392 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003393 break;
3394
3395 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003396 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003397 break;
3398
3399 default:
3400 UNREACHABLE();
3401 return;
3402 }
3403}
3404
3405void Context::lineWidth(GLfloat width)
3406{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003407 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003408}
3409
3410void Context::pixelStorei(GLenum pname, GLint param)
3411{
3412 switch (pname)
3413 {
3414 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003415 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003416 break;
3417
3418 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420 break;
3421
3422 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003423 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003424 break;
3425
3426 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003427 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003428 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003429 break;
3430
3431 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003432 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003433 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003434 break;
3435
3436 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003437 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003438 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003439 break;
3440
3441 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003442 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003443 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003444 break;
3445
3446 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003447 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003448 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003449 break;
3450
3451 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003452 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003453 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003454 break;
3455
3456 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003457 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003458 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003459 break;
3460
3461 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003462 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003463 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003464 break;
3465
3466 default:
3467 UNREACHABLE();
3468 return;
3469 }
3470}
3471
3472void Context::polygonOffset(GLfloat factor, GLfloat units)
3473{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003474 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003475}
3476
3477void Context::sampleCoverage(GLclampf value, GLboolean invert)
3478{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003479 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003480}
3481
3482void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3483{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003484 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003485}
3486
3487void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3488{
3489 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3490 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003491 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003492 }
3493
3494 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3495 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003496 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003497 }
3498}
3499
3500void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3501{
3502 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3503 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003504 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003505 }
3506
3507 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3508 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003509 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003510 }
3511}
3512
3513void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3514{
3515 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3516 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003517 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003518 }
3519
3520 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3521 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003522 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003523 }
3524}
3525
3526void Context::vertexAttrib1f(GLuint index, GLfloat x)
3527{
3528 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003530}
3531
3532void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3533{
3534 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003535 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003536}
3537
3538void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3539{
3540 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003541 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003542}
3543
3544void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3545{
3546 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003547 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003548}
3549
3550void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3551{
3552 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003553 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003554}
3555
3556void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3557{
3558 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003559 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003560}
3561
3562void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3563{
3564 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003565 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003566}
3567
3568void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3569{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003570 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003571}
3572
3573void Context::vertexAttribPointer(GLuint index,
3574 GLint size,
3575 GLenum type,
3576 GLboolean normalized,
3577 GLsizei stride,
3578 const GLvoid *ptr)
3579{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003580 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3581 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003582}
3583
3584void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3585{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003586 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003587}
3588
3589void Context::vertexAttribIPointer(GLuint index,
3590 GLint size,
3591 GLenum type,
3592 GLsizei stride,
3593 const GLvoid *pointer)
3594{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003595 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3596 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003597}
3598
3599void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3600{
3601 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003602 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003603}
3604
3605void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3606{
3607 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003608 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003609}
3610
3611void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3612{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003613 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003614}
3615
3616void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3617{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003618 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003619}
3620
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003621void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3622{
3623 const VertexAttribCurrentValueData &currentValues =
3624 getGLState().getVertexAttribCurrentValue(index);
3625 const VertexArray *vao = getGLState().getVertexArray();
3626 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3627 currentValues, pname, params);
3628}
3629
3630void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3631{
3632 const VertexAttribCurrentValueData &currentValues =
3633 getGLState().getVertexAttribCurrentValue(index);
3634 const VertexArray *vao = getGLState().getVertexArray();
3635 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3636 currentValues, pname, params);
3637}
3638
3639void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3640{
3641 const VertexAttribCurrentValueData &currentValues =
3642 getGLState().getVertexAttribCurrentValue(index);
3643 const VertexArray *vao = getGLState().getVertexArray();
3644 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3645 currentValues, pname, params);
3646}
3647
3648void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3649{
3650 const VertexAttribCurrentValueData &currentValues =
3651 getGLState().getVertexAttribCurrentValue(index);
3652 const VertexArray *vao = getGLState().getVertexArray();
3653 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3654 currentValues, pname, params);
3655}
3656
3657void Context::getVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
3658{
3659 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3660 QueryVertexAttribPointerv(attrib, pname, pointer);
3661}
3662
Jamie Madillc20ab272016-06-09 07:20:46 -07003663void Context::debugMessageControl(GLenum source,
3664 GLenum type,
3665 GLenum severity,
3666 GLsizei count,
3667 const GLuint *ids,
3668 GLboolean enabled)
3669{
3670 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003671 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3672 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003673}
3674
3675void Context::debugMessageInsert(GLenum source,
3676 GLenum type,
3677 GLuint id,
3678 GLenum severity,
3679 GLsizei length,
3680 const GLchar *buf)
3681{
3682 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003683 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003684}
3685
3686void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3687{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003688 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003689}
3690
3691GLuint Context::getDebugMessageLog(GLuint count,
3692 GLsizei bufSize,
3693 GLenum *sources,
3694 GLenum *types,
3695 GLuint *ids,
3696 GLenum *severities,
3697 GLsizei *lengths,
3698 GLchar *messageLog)
3699{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003700 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3701 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003702}
3703
3704void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3705{
3706 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003707 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003708}
3709
3710void Context::popDebugGroup()
3711{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003712 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003713}
3714
Jamie Madill29639852016-09-02 15:00:09 -04003715void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3716{
3717 Buffer *buffer = mGLState.getTargetBuffer(target);
3718 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003719 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003720}
3721
3722void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3723{
3724 if (data == nullptr)
3725 {
3726 return;
3727 }
3728
3729 Buffer *buffer = mGLState.getTargetBuffer(target);
3730 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003731 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003732}
3733
Jamie Madillef300b12016-10-07 15:12:09 -04003734void Context::attachShader(GLuint program, GLuint shader)
3735{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003736 auto programObject = mState.mShaderPrograms->getProgram(program);
3737 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003738 ASSERT(programObject && shaderObject);
3739 programObject->attachShader(shaderObject);
3740}
3741
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003742const Workarounds &Context::getWorkarounds() const
3743{
3744 return mWorkarounds;
3745}
3746
Jamie Madillb0817d12016-11-01 15:48:31 -04003747void Context::copyBufferSubData(GLenum readTarget,
3748 GLenum writeTarget,
3749 GLintptr readOffset,
3750 GLintptr writeOffset,
3751 GLsizeiptr size)
3752{
3753 // if size is zero, the copy is a successful no-op
3754 if (size == 0)
3755 {
3756 return;
3757 }
3758
3759 // TODO(jmadill): cache these.
3760 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3761 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3762
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003763 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003764}
3765
Jamie Madill01a80ee2016-11-07 12:06:18 -05003766void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3767{
3768 Program *programObject = getProgram(program);
3769 // TODO(jmadill): Re-use this from the validation if possible.
3770 ASSERT(programObject);
3771 programObject->bindAttributeLocation(index, name);
3772}
3773
3774void Context::bindBuffer(GLenum target, GLuint buffer)
3775{
3776 switch (target)
3777 {
3778 case GL_ARRAY_BUFFER:
3779 bindArrayBuffer(buffer);
3780 break;
3781 case GL_ELEMENT_ARRAY_BUFFER:
3782 bindElementArrayBuffer(buffer);
3783 break;
3784 case GL_COPY_READ_BUFFER:
3785 bindCopyReadBuffer(buffer);
3786 break;
3787 case GL_COPY_WRITE_BUFFER:
3788 bindCopyWriteBuffer(buffer);
3789 break;
3790 case GL_PIXEL_PACK_BUFFER:
3791 bindPixelPackBuffer(buffer);
3792 break;
3793 case GL_PIXEL_UNPACK_BUFFER:
3794 bindPixelUnpackBuffer(buffer);
3795 break;
3796 case GL_UNIFORM_BUFFER:
3797 bindGenericUniformBuffer(buffer);
3798 break;
3799 case GL_TRANSFORM_FEEDBACK_BUFFER:
3800 bindGenericTransformFeedbackBuffer(buffer);
3801 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003802 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003803 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003804 break;
3805 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003806 if (buffer != 0)
3807 {
3808 // Binding buffers to this binding point is not implemented yet.
3809 UNIMPLEMENTED();
3810 }
Geoff Lang3b573612016-10-31 14:08:10 -04003811 break;
3812 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003813 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003814 break;
3815 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003816 if (buffer != 0)
3817 {
3818 // Binding buffers to this binding point is not implemented yet.
3819 UNIMPLEMENTED();
3820 }
Geoff Lang3b573612016-10-31 14:08:10 -04003821 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003822
3823 default:
3824 UNREACHABLE();
3825 break;
3826 }
3827}
3828
Jiajia Qin6eafb042016-12-27 17:04:07 +08003829void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3830{
3831 bindBufferRange(target, index, buffer, 0, 0);
3832}
3833
3834void Context::bindBufferRange(GLenum target,
3835 GLuint index,
3836 GLuint buffer,
3837 GLintptr offset,
3838 GLsizeiptr size)
3839{
3840 switch (target)
3841 {
3842 case GL_TRANSFORM_FEEDBACK_BUFFER:
3843 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3844 bindGenericTransformFeedbackBuffer(buffer);
3845 break;
3846 case GL_UNIFORM_BUFFER:
3847 bindIndexedUniformBuffer(buffer, index, offset, size);
3848 bindGenericUniformBuffer(buffer);
3849 break;
3850 case GL_ATOMIC_COUNTER_BUFFER:
3851 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3852 bindGenericAtomicCounterBuffer(buffer);
3853 break;
3854 case GL_SHADER_STORAGE_BUFFER:
3855 if (buffer != 0)
3856 {
3857 // Binding buffers to this binding point is not implemented yet.
3858 UNIMPLEMENTED();
3859 }
3860 break;
3861 default:
3862 UNREACHABLE();
3863 break;
3864 }
3865}
3866
Jamie Madill01a80ee2016-11-07 12:06:18 -05003867void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3868{
3869 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3870 {
3871 bindReadFramebuffer(framebuffer);
3872 }
3873
3874 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3875 {
3876 bindDrawFramebuffer(framebuffer);
3877 }
3878}
3879
3880void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3881{
3882 ASSERT(target == GL_RENDERBUFFER);
3883 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003884 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003885 mGLState.setRenderbufferBinding(object);
3886}
3887
JiangYizhoubddc46b2016-12-09 09:50:51 +08003888void Context::texStorage2DMultisample(GLenum target,
3889 GLsizei samples,
3890 GLenum internalformat,
3891 GLsizei width,
3892 GLsizei height,
3893 GLboolean fixedsamplelocations)
3894{
3895 Extents size(width, height, 1);
3896 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003897 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003898 fixedsamplelocations));
3899}
3900
3901void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3902{
3903 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3904 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3905
3906 switch (pname)
3907 {
3908 case GL_SAMPLE_POSITION:
3909 handleError(framebuffer->getSamplePosition(index, val));
3910 break;
3911 default:
3912 UNREACHABLE();
3913 }
3914}
3915
Jamie Madille8fb6402017-02-14 17:56:40 -05003916void Context::renderbufferStorage(GLenum target,
3917 GLenum internalformat,
3918 GLsizei width,
3919 GLsizei height)
3920{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003921 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3922 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
3923
Jamie Madille8fb6402017-02-14 17:56:40 -05003924 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003925 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003926}
3927
3928void Context::renderbufferStorageMultisample(GLenum target,
3929 GLsizei samples,
3930 GLenum internalformat,
3931 GLsizei width,
3932 GLsizei height)
3933{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003934 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
3935 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05003936
3937 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05003938 handleError(
3939 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05003940}
3941
JiangYizhoue18e6392017-02-20 10:32:23 +08003942void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
3943{
3944 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3945 QueryFramebufferParameteriv(framebuffer, pname, params);
3946}
3947
3948void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
3949{
3950 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3951 SetFramebufferParameteri(framebuffer, pname, param);
3952}
3953
Jamie Madille14951e2017-03-09 18:55:16 -05003954Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
3955{
3956 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
3957 {
3958 return gl::OutOfMemory() << "Failed to allocate internal buffer.";
3959 }
3960 return gl::NoError();
3961}
3962
Jamie Madillc29968b2016-01-20 11:17:23 -05003963} // namespace gl