blob: c44bab60f5d51d1297f128b718a9753386f464e0 [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"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050023#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Fence.h"
25#include "libANGLE/Framebuffer.h"
26#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Query.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
Martin Radev9d901792016-07-15 15:58:58 +0300202std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
203{
204 std::string labelName;
205 if (label != nullptr)
206 {
207 size_t labelLength = length < 0 ? strlen(label) : length;
208 labelName = std::string(label, labelLength);
209 }
210 return labelName;
211}
212
213void GetObjectLabelBase(const std::string &objectLabel,
214 GLsizei bufSize,
215 GLsizei *length,
216 GLchar *label)
217{
218 size_t writeLength = objectLabel.length();
219 if (label != nullptr && bufSize > 0)
220 {
221 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
222 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
223 label[writeLength] = '\0';
224 }
225
226 if (length != nullptr)
227 {
228 *length = static_cast<GLsizei>(writeLength);
229 }
230}
231
Geoff Langf6db0982015-08-25 13:04:00 -0400232} // anonymous namespace
233
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000234namespace gl
235{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000236
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400237Context::Context(rx::EGLImplFactory *implFactory,
238 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400239 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500240 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300241
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500242 : ValidationContext(shareContext,
243 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700244 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500245 mCaps,
246 mTextureCaps,
247 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500248 mLimitations,
Jamie Madill01a80ee2016-11-07 12:06:18 -0500249 mFramebufferMap,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500250 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700251 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500252 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400253 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500254 mClientType(EGL_OPENGL_ES_API),
255 mHasBeenCurrent(false),
256 mContextLost(false),
257 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700258 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500259 mResetStrategy(GetResetStrategy(attribs)),
260 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500261 mCurrentSurface(nullptr),
262 mSurfacelessFramebuffer(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000263{
Geoff Lang077f20a2016-11-01 10:08:02 -0400264 if (mRobustAccess)
265 {
266 UNIMPLEMENTED();
267 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000268
Geoff Langc287ea62016-09-16 14:46:51 -0400269 initCaps(GetWebGLContext(attribs));
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700270 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400271
Geoff Langeb66a6e2016-10-31 13:06:12 -0400272 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400273 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100274
Shannon Woods53a94a82014-06-24 15:20:36 -0400275 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400276
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277 // [OpenGL ES 2.0.24] section 3.7 page 83:
278 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
279 // and cube map texture state vectors respectively associated with them.
280 // In order that access to these initial textures not be lost, they are treated as texture
281 // objects all of whose names are 0.
282
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400283 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500284 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500285
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400286 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500287 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400288
Geoff Langeb66a6e2016-10-31 13:06:12 -0400289 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400290 {
291 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400292 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500293 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400294
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400295 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500296 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400297 }
Geoff Lang3b573612016-10-31 14:08:10 -0400298 if (getClientVersion() >= Version(3, 1))
299 {
300 Texture *zeroTexture2DMultisample =
301 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
302 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
303 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000304
Ian Ewellbda75592016-04-18 17:25:54 -0400305 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
306 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTextureExternal =
308 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400309 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
310 }
311
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700312 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500313
Jamie Madill57a89722013-07-02 11:57:03 -0400314 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000315 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800316 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000317 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400318
Jamie Madill01a80ee2016-11-07 12:06:18 -0500319 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000320
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000321 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500322 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000323 {
324 bindIndexedUniformBuffer(0, i, 0, -1);
325 }
326
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000327 bindCopyReadBuffer(0);
328 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000329 bindPixelPackBuffer(0);
330 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000331
Geoff Langeb66a6e2016-10-31 13:06:12 -0400332 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400333 {
334 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
335 // In the initial state, a default transform feedback object is bound and treated as
336 // a transform feedback object with a name of zero. That object is bound any time
337 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400338 bindTransformFeedback(0);
339 }
Geoff Langc8058452014-02-03 12:04:11 -0500340
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700341 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500342
343 // Initialize dirty bit masks
344 // TODO(jmadill): additional ES3 state
345 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
346 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
347 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
348 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
349 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
350 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400351 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500352 // No dirty objects.
353
354 // Readpixels uses the pack state and read FBO
355 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
356 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
357 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
358 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
359 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400360 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500361 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
362
363 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
364 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
365 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
366 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
367 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
368 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
369 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
370 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
371 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
372 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
373 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
374 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
375
376 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
377 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700378 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500379 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
380 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400381
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400382 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000383}
384
385Context::~Context()
386{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700387 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000388
Corentin Wallez37c39792015-08-20 14:19:46 -0400389 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000390 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400391 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400392 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400393 {
394 SafeDelete(framebuffer.second);
395 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000396 }
397
Corentin Wallez80b24112015-08-25 16:41:57 -0400398 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000399 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400400 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000401 }
402
Corentin Wallez80b24112015-08-25 16:41:57 -0400403 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000404 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400405 if (query.second != nullptr)
406 {
407 query.second->release();
408 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000409 }
410
Corentin Wallez80b24112015-08-25 16:41:57 -0400411 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400412 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400413 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400414 }
415
Corentin Wallez80b24112015-08-25 16:41:57 -0400416 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500417 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500418 if (transformFeedback.second != nullptr)
419 {
420 transformFeedback.second->release();
421 }
Geoff Langc8058452014-02-03 12:04:11 -0500422 }
423
Jamie Madilldedd7b92014-11-05 16:30:36 -0500424 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400425 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500426 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400427 }
428 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429
Corentin Wallezccab69d2017-01-27 16:57:15 -0500430 SafeDelete(mSurfacelessFramebuffer);
431
Corentin Wallez51706ea2015-08-07 14:39:22 -0400432 if (mCurrentSurface != nullptr)
433 {
434 releaseSurface();
435 }
436
Geoff Lang492a7e42014-11-05 13:27:06 -0500437 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438}
439
daniel@transgaming.comad629872012-11-28 19:32:06 +0000440void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000441{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000442 if (!mHasBeenCurrent)
443 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000444 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500445 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400446 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000447
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700448 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
449 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000450
451 mHasBeenCurrent = true;
452 }
453
Jamie Madill1b94d432015-08-07 13:23:23 -0400454 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700455 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400456
Corentin Wallez51706ea2015-08-07 14:39:22 -0400457 if (mCurrentSurface)
458 {
459 releaseSurface();
460 }
Corentin Wallezccab69d2017-01-27 16:57:15 -0500461
462 Framebuffer *newDefault = nullptr;
463 if (surface != nullptr)
464 {
465 surface->setIsCurrent(true);
466 mCurrentSurface = surface;
467 newDefault = surface->getDefaultFramebuffer();
468 }
469 else
470 {
471 if (mSurfacelessFramebuffer == nullptr)
472 {
473 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
474 }
475
476 newDefault = mSurfacelessFramebuffer;
477 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000478
Corentin Wallez37c39792015-08-20 14:19:46 -0400479 // Update default framebuffer, the binding of the previous default
480 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400481 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700482 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400483 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700484 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400485 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700486 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400487 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700488 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400489 }
490 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400491 }
Ian Ewell292f0052016-02-04 10:37:32 -0500492
493 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700494 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000495}
496
Jamie Madill77a72f62015-04-14 11:18:32 -0400497void Context::releaseSurface()
498{
Corentin Wallez37c39792015-08-20 14:19:46 -0400499 ASSERT(mCurrentSurface != nullptr);
500
501 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400502 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400503 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700504 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400505 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700506 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400507 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700508 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400509 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700510 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400511 }
512 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400513 }
514
Corentin Wallez51706ea2015-08-07 14:39:22 -0400515 mCurrentSurface->setIsCurrent(false);
516 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400517}
518
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000519GLuint Context::createBuffer()
520{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500521 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000522}
523
524GLuint Context::createProgram()
525{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500526 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000527}
528
529GLuint Context::createShader(GLenum type)
530{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500531 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000532}
533
534GLuint Context::createTexture()
535{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500536 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000537}
538
539GLuint Context::createRenderbuffer()
540{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500541 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000542}
543
Geoff Lang882033e2014-09-30 11:26:07 -0400544GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400545{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500546 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400547
Cooper Partind8e62a32015-01-29 15:21:25 -0800548 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400549}
550
Sami Väisänene45e53b2016-05-25 10:36:04 +0300551GLuint Context::createPaths(GLsizei range)
552{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500553 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300554 if (resultOrError.isError())
555 {
556 handleError(resultOrError.getError());
557 return 0;
558 }
559 return resultOrError.getResult();
560}
561
Jamie Madill57a89722013-07-02 11:57:03 -0400562GLuint Context::createVertexArray()
563{
Geoff Lang36167ab2015-12-07 10:27:14 -0500564 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
565 mVertexArrayMap[vertexArray] = nullptr;
566 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400567}
568
Jamie Madilldc356042013-07-19 16:36:57 -0400569GLuint Context::createSampler()
570{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500571 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400572}
573
Geoff Langc8058452014-02-03 12:04:11 -0500574GLuint Context::createTransformFeedback()
575{
Geoff Lang36167ab2015-12-07 10:27:14 -0500576 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
577 mTransformFeedbackMap[transformFeedback] = nullptr;
578 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500579}
580
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000581// Returns an unused framebuffer name
582GLuint Context::createFramebuffer()
583{
584 GLuint handle = mFramebufferHandleAllocator.allocate();
585
586 mFramebufferMap[handle] = NULL;
587
588 return handle;
589}
590
Jamie Madill33dc8432013-07-26 11:55:05 -0400591GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592{
Jamie Madill33dc8432013-07-26 11:55:05 -0400593 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000594
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400595 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000596
597 return handle;
598}
599
600// Returns an unused query name
601GLuint Context::createQuery()
602{
603 GLuint handle = mQueryHandleAllocator.allocate();
604
605 mQueryMap[handle] = NULL;
606
607 return handle;
608}
609
610void Context::deleteBuffer(GLuint buffer)
611{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500612 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000613 {
614 detachBuffer(buffer);
615 }
Jamie Madill893ab082014-05-16 16:56:10 -0400616
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500617 mState.mBuffers->deleteBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000618}
619
620void Context::deleteShader(GLuint shader)
621{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500622 mState.mShaderPrograms->deleteShader(shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000623}
624
625void Context::deleteProgram(GLuint program)
626{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500627 mState.mShaderPrograms->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000628}
629
630void Context::deleteTexture(GLuint texture)
631{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500632 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633 {
634 detachTexture(texture);
635 }
636
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500637 mState.mTextures->deleteTexture(texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000638}
639
640void Context::deleteRenderbuffer(GLuint renderbuffer)
641{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500642 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000643 {
644 detachRenderbuffer(renderbuffer);
645 }
Jamie Madill893ab082014-05-16 16:56:10 -0400646
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500647 mState.mRenderbuffers->deleteRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000648}
649
Jamie Madillcd055f82013-07-26 11:55:15 -0400650void Context::deleteFenceSync(GLsync fenceSync)
651{
652 // The spec specifies the underlying Fence object is not deleted until all current
653 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
654 // and since our API is currently designed for being called from a single thread, we can delete
655 // the fence immediately.
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500656 mState.mFenceSyncs->deleteFenceSync(
657 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400658}
659
Sami Väisänene45e53b2016-05-25 10:36:04 +0300660void Context::deletePaths(GLuint first, GLsizei range)
661{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500662 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300663}
664
665bool Context::hasPathData(GLuint path) const
666{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500667 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300668 if (pathObj == nullptr)
669 return false;
670
671 return pathObj->hasPathData();
672}
673
674bool Context::hasPath(GLuint path) const
675{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500676 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300677}
678
679void Context::setPathCommands(GLuint path,
680 GLsizei numCommands,
681 const GLubyte *commands,
682 GLsizei numCoords,
683 GLenum coordType,
684 const void *coords)
685{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500686 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300687
688 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
689}
690
691void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
692{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500693 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300694
695 switch (pname)
696 {
697 case GL_PATH_STROKE_WIDTH_CHROMIUM:
698 pathObj->setStrokeWidth(value);
699 break;
700 case GL_PATH_END_CAPS_CHROMIUM:
701 pathObj->setEndCaps(static_cast<GLenum>(value));
702 break;
703 case GL_PATH_JOIN_STYLE_CHROMIUM:
704 pathObj->setJoinStyle(static_cast<GLenum>(value));
705 break;
706 case GL_PATH_MITER_LIMIT_CHROMIUM:
707 pathObj->setMiterLimit(value);
708 break;
709 case GL_PATH_STROKE_BOUND_CHROMIUM:
710 pathObj->setStrokeBound(value);
711 break;
712 default:
713 UNREACHABLE();
714 break;
715 }
716}
717
718void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
719{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500720 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300721
722 switch (pname)
723 {
724 case GL_PATH_STROKE_WIDTH_CHROMIUM:
725 *value = pathObj->getStrokeWidth();
726 break;
727 case GL_PATH_END_CAPS_CHROMIUM:
728 *value = static_cast<GLfloat>(pathObj->getEndCaps());
729 break;
730 case GL_PATH_JOIN_STYLE_CHROMIUM:
731 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
732 break;
733 case GL_PATH_MITER_LIMIT_CHROMIUM:
734 *value = pathObj->getMiterLimit();
735 break;
736 case GL_PATH_STROKE_BOUND_CHROMIUM:
737 *value = pathObj->getStrokeBound();
738 break;
739 default:
740 UNREACHABLE();
741 break;
742 }
743}
744
745void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
746{
747 mGLState.setPathStencilFunc(func, ref, mask);
748}
749
Jamie Madill57a89722013-07-02 11:57:03 -0400750void Context::deleteVertexArray(GLuint vertexArray)
751{
Geoff Lang36167ab2015-12-07 10:27:14 -0500752 auto iter = mVertexArrayMap.find(vertexArray);
753 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000754 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500755 VertexArray *vertexArrayObject = iter->second;
756 if (vertexArrayObject != nullptr)
757 {
758 detachVertexArray(vertexArray);
759 delete vertexArrayObject;
760 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000761
Geoff Lang36167ab2015-12-07 10:27:14 -0500762 mVertexArrayMap.erase(iter);
763 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400764 }
765}
766
Jamie Madilldc356042013-07-19 16:36:57 -0400767void Context::deleteSampler(GLuint sampler)
768{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500769 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400770 {
771 detachSampler(sampler);
772 }
773
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500774 mState.mSamplers->deleteSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400775}
776
Geoff Langc8058452014-02-03 12:04:11 -0500777void Context::deleteTransformFeedback(GLuint transformFeedback)
778{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500779 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500780 if (iter != mTransformFeedbackMap.end())
781 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500782 TransformFeedback *transformFeedbackObject = iter->second;
783 if (transformFeedbackObject != nullptr)
784 {
785 detachTransformFeedback(transformFeedback);
786 transformFeedbackObject->release();
787 }
788
Geoff Lang50b3fe82015-12-08 14:49:12 +0000789 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500790 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500791 }
792}
793
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794void Context::deleteFramebuffer(GLuint framebuffer)
795{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500796 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000797
798 if (framebufferObject != mFramebufferMap.end())
799 {
800 detachFramebuffer(framebuffer);
801
802 mFramebufferHandleAllocator.release(framebufferObject->first);
803 delete framebufferObject->second;
804 mFramebufferMap.erase(framebufferObject);
805 }
806}
807
Jamie Madill33dc8432013-07-26 11:55:05 -0400808void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000809{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500810 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000811
Jamie Madill33dc8432013-07-26 11:55:05 -0400812 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400814 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400816 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000817 }
818}
819
820void Context::deleteQuery(GLuint query)
821{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500822 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000823 if (queryObject != mQueryMap.end())
824 {
825 mQueryHandleAllocator.release(queryObject->first);
826 if (queryObject->second)
827 {
828 queryObject->second->release();
829 }
830 mQueryMap.erase(queryObject);
831 }
832}
833
Geoff Lang70d0f492015-12-10 17:45:46 -0500834Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500836 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837}
838
Jamie Madill570f7c82014-07-03 10:38:54 -0400839Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500841 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000842}
843
Geoff Lang70d0f492015-12-10 17:45:46 -0500844Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000845{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500846 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847}
848
Jamie Madillcd055f82013-07-26 11:55:15 -0400849FenceSync *Context::getFenceSync(GLsync handle) const
850{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500851 return mState.mFenceSyncs->getFenceSync(
852 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400853}
854
Jamie Madill57a89722013-07-02 11:57:03 -0400855VertexArray *Context::getVertexArray(GLuint handle) const
856{
857 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500858 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400859}
860
Jamie Madilldc356042013-07-19 16:36:57 -0400861Sampler *Context::getSampler(GLuint handle) const
862{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500863 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400864}
865
Geoff Langc8058452014-02-03 12:04:11 -0500866TransformFeedback *Context::getTransformFeedback(GLuint handle) const
867{
Geoff Lang36167ab2015-12-07 10:27:14 -0500868 auto iter = mTransformFeedbackMap.find(handle);
869 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500870}
871
Geoff Lang70d0f492015-12-10 17:45:46 -0500872LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
873{
874 switch (identifier)
875 {
876 case GL_BUFFER:
877 return getBuffer(name);
878 case GL_SHADER:
879 return getShader(name);
880 case GL_PROGRAM:
881 return getProgram(name);
882 case GL_VERTEX_ARRAY:
883 return getVertexArray(name);
884 case GL_QUERY:
885 return getQuery(name);
886 case GL_TRANSFORM_FEEDBACK:
887 return getTransformFeedback(name);
888 case GL_SAMPLER:
889 return getSampler(name);
890 case GL_TEXTURE:
891 return getTexture(name);
892 case GL_RENDERBUFFER:
893 return getRenderbuffer(name);
894 case GL_FRAMEBUFFER:
895 return getFramebuffer(name);
896 default:
897 UNREACHABLE();
898 return nullptr;
899 }
900}
901
902LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
903{
904 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
905}
906
Martin Radev9d901792016-07-15 15:58:58 +0300907void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
908{
909 LabeledObject *object = getLabeledObject(identifier, name);
910 ASSERT(object != nullptr);
911
912 std::string labelName = GetObjectLabelFromPointer(length, label);
913 object->setLabel(labelName);
914}
915
916void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
917{
918 LabeledObject *object = getLabeledObjectFromPtr(ptr);
919 ASSERT(object != nullptr);
920
921 std::string labelName = GetObjectLabelFromPointer(length, label);
922 object->setLabel(labelName);
923}
924
925void Context::getObjectLabel(GLenum identifier,
926 GLuint name,
927 GLsizei bufSize,
928 GLsizei *length,
929 GLchar *label) const
930{
931 LabeledObject *object = getLabeledObject(identifier, name);
932 ASSERT(object != nullptr);
933
934 const std::string &objectLabel = object->getLabel();
935 GetObjectLabelBase(objectLabel, bufSize, length, label);
936}
937
938void Context::getObjectPtrLabel(const void *ptr,
939 GLsizei bufSize,
940 GLsizei *length,
941 GLchar *label) const
942{
943 LabeledObject *object = getLabeledObjectFromPtr(ptr);
944 ASSERT(object != nullptr);
945
946 const std::string &objectLabel = object->getLabel();
947 GetObjectLabelBase(objectLabel, bufSize, length, label);
948}
949
Jamie Madilldc356042013-07-19 16:36:57 -0400950bool Context::isSampler(GLuint samplerName) const
951{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500952 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400953}
954
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500955void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000956{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500957 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700958 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000959}
960
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800961void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
962{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500963 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800964 mGLState.setDrawIndirectBufferBinding(buffer);
965}
966
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500967void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000968{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500969 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700970 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000971}
972
Jamie Madilldedd7b92014-11-05 16:30:36 -0500973void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500975 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976
Jamie Madilldedd7b92014-11-05 16:30:36 -0500977 if (handle == 0)
978 {
979 texture = mZeroTextures[target].get();
980 }
981 else
982 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500983 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500984 }
985
986 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700987 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000988}
989
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500990void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000991{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500992 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700993 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000994}
995
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500996void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000997{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500998 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700999 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001000}
1001
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001002void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001003{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001004 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001005 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001006}
1007
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001008void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001009{
Geoff Lang76b10c92014-09-05 16:28:14 -04001010 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001011 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001012 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001013 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001014}
1015
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001016void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001017{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001018 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001019 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001020}
1021
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001022void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1023 GLuint index,
1024 GLintptr offset,
1025 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001026{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001027 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001028 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001029}
1030
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001031void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001032{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001033 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001034 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1038 GLuint index,
1039 GLintptr offset,
1040 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001041{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001042 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001043 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001044}
1045
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001046void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001047{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001048 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001049 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001050}
1051
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001052void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001053{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001054 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001055 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001056}
1057
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001058void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001059{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001060 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001061 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001062}
1063
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001064void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001065{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001066 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001067 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001068}
1069
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001070void Context::useProgram(GLuint program)
1071{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001072 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001073}
1074
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001075void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001076{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001077 TransformFeedback *transformFeedback =
1078 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001079 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001080}
1081
Geoff Lang5aad9672014-09-08 11:10:42 -04001082Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001083{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001084 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001085 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001086
Geoff Lang5aad9672014-09-08 11:10:42 -04001087 // begin query
1088 Error error = queryObject->begin();
1089 if (error.isError())
1090 {
1091 return error;
1092 }
1093
1094 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001095 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001096
He Yunchaoacd18982017-01-04 10:46:42 +08001097 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001098}
1099
Geoff Lang5aad9672014-09-08 11:10:42 -04001100Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001101{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001102 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001103 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001104
Geoff Lang5aad9672014-09-08 11:10:42 -04001105 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106
Geoff Lang5aad9672014-09-08 11:10:42 -04001107 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001108 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001109
1110 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001111}
1112
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001113Error Context::queryCounter(GLuint id, GLenum target)
1114{
1115 ASSERT(target == GL_TIMESTAMP_EXT);
1116
1117 Query *queryObject = getQuery(id, true, target);
1118 ASSERT(queryObject);
1119
1120 return queryObject->queryCounter();
1121}
1122
1123void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1124{
1125 switch (pname)
1126 {
1127 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001128 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001129 break;
1130 case GL_QUERY_COUNTER_BITS_EXT:
1131 switch (target)
1132 {
1133 case GL_TIME_ELAPSED_EXT:
1134 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1135 break;
1136 case GL_TIMESTAMP_EXT:
1137 params[0] = getExtensions().queryCounterBitsTimestamp;
1138 break;
1139 default:
1140 UNREACHABLE();
1141 params[0] = 0;
1142 break;
1143 }
1144 break;
1145 default:
1146 UNREACHABLE();
1147 return;
1148 }
1149}
1150
Geoff Lang2186c382016-10-14 10:54:54 -04001151void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001152{
Geoff Lang2186c382016-10-14 10:54:54 -04001153 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001154}
1155
Geoff Lang2186c382016-10-14 10:54:54 -04001156void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001157{
Geoff Lang2186c382016-10-14 10:54:54 -04001158 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001159}
1160
Geoff Lang2186c382016-10-14 10:54:54 -04001161void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001162{
Geoff Lang2186c382016-10-14 10:54:54 -04001163 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001164}
1165
Geoff Lang2186c382016-10-14 10:54:54 -04001166void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001167{
Geoff Lang2186c382016-10-14 10:54:54 -04001168 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001169}
1170
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001171Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001173 auto framebufferIt = mFramebufferMap.find(handle);
1174 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175}
1176
Jamie Madill33dc8432013-07-26 11:55:05 -04001177FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001178{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001179 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180
Jamie Madill33dc8432013-07-26 11:55:05 -04001181 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001182 {
1183 return NULL;
1184 }
1185 else
1186 {
1187 return fence->second;
1188 }
1189}
1190
1191Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1192{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001193 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001194
1195 if (query == mQueryMap.end())
1196 {
1197 return NULL;
1198 }
1199 else
1200 {
1201 if (!query->second && create)
1202 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001203 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001204 query->second->addRef();
1205 }
1206 return query->second;
1207 }
1208}
1209
Geoff Lang70d0f492015-12-10 17:45:46 -05001210Query *Context::getQuery(GLuint handle) const
1211{
1212 auto iter = mQueryMap.find(handle);
1213 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1214}
1215
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001216Texture *Context::getTargetTexture(GLenum target) const
1217{
Ian Ewellbda75592016-04-18 17:25:54 -04001218 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001219 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001220}
1221
Geoff Lang76b10c92014-09-05 16:28:14 -04001222Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001224 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225}
1226
Geoff Lang492a7e42014-11-05 13:27:06 -05001227Compiler *Context::getCompiler() const
1228{
1229 return mCompiler;
1230}
1231
Jamie Madill893ab082014-05-16 16:56:10 -04001232void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233{
1234 switch (pname)
1235 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001236 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001237 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001239 mGLState.getBooleanv(pname, params);
1240 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242}
1243
Jamie Madill893ab082014-05-16 16:56:10 -04001244void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001245{
Shannon Woods53a94a82014-06-24 15:20:36 -04001246 // Queries about context capabilities and maximums are answered by Context.
1247 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001248 switch (pname)
1249 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001251 params[0] = mCaps.minAliasedLineWidth;
1252 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001253 break;
1254 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001255 params[0] = mCaps.minAliasedPointSize;
1256 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001257 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001258 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001259 ASSERT(mExtensions.textureFilterAnisotropic);
1260 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001261 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001262 case GL_MAX_TEXTURE_LOD_BIAS:
1263 *params = mCaps.maxLODBias;
1264 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001265
1266 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1267 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1268 {
1269 ASSERT(mExtensions.pathRendering);
1270 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1271 memcpy(params, m, 16 * sizeof(GLfloat));
1272 }
1273 break;
1274
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001276 mGLState.getFloatv(pname, params);
1277 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279}
1280
Jamie Madill893ab082014-05-16 16:56:10 -04001281void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001282{
Shannon Woods53a94a82014-06-24 15:20:36 -04001283 // Queries about context capabilities and maximums are answered by Context.
1284 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001285
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001286 switch (pname)
1287 {
Geoff Lang301d1612014-07-09 10:34:37 -04001288 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1289 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1290 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001291 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1292 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1293 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001294 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1295 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1296 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001297 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001298 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1299 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1300 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001301 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001302 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001303 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1304 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1305 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1306 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001307 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1308 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001309 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1310 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001311 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001312 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1313 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1314 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1315 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001316 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001317 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001318 break;
1319 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001320 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001321 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001322 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1323 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001324 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1325 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1326 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001327 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1328 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1329 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001330 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001331 case GL_MAX_VIEWPORT_DIMS:
1332 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001333 params[0] = mCaps.maxViewportWidth;
1334 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001335 }
1336 break;
1337 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001338 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001339 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001340 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1341 *params = mResetStrategy;
1342 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001343 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001344 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001345 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001346 case GL_SHADER_BINARY_FORMATS:
1347 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1348 break;
1349 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001350 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001351 break;
1352 case GL_PROGRAM_BINARY_FORMATS:
1353 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001354 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001355 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001356 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001357 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001358
1359 // GL_KHR_debug
1360 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1361 *params = mExtensions.maxDebugMessageLength;
1362 break;
1363 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1364 *params = mExtensions.maxDebugLoggedMessages;
1365 break;
1366 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1367 *params = mExtensions.maxDebugGroupStackDepth;
1368 break;
1369 case GL_MAX_LABEL_LENGTH:
1370 *params = mExtensions.maxLabelLength;
1371 break;
1372
Ian Ewell53f59f42016-01-28 17:36:55 -05001373 // GL_EXT_disjoint_timer_query
1374 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001375 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001376 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001377 case GL_MAX_FRAMEBUFFER_WIDTH:
1378 *params = mCaps.maxFramebufferWidth;
1379 break;
1380 case GL_MAX_FRAMEBUFFER_HEIGHT:
1381 *params = mCaps.maxFramebufferHeight;
1382 break;
1383 case GL_MAX_FRAMEBUFFER_SAMPLES:
1384 *params = mCaps.maxFramebufferSamples;
1385 break;
1386 case GL_MAX_SAMPLE_MASK_WORDS:
1387 *params = mCaps.maxSampleMaskWords;
1388 break;
1389 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1390 *params = mCaps.maxColorTextureSamples;
1391 break;
1392 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1393 *params = mCaps.maxDepthTextureSamples;
1394 break;
1395 case GL_MAX_INTEGER_SAMPLES:
1396 *params = mCaps.maxIntegerSamples;
1397 break;
1398 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1399 *params = mCaps.maxVertexAttribRelativeOffset;
1400 break;
1401 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1402 *params = mCaps.maxVertexAttribBindings;
1403 break;
1404 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1405 *params = mCaps.maxVertexAttribStride;
1406 break;
1407 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1408 *params = mCaps.maxVertexAtomicCounterBuffers;
1409 break;
1410 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1411 *params = mCaps.maxVertexAtomicCounters;
1412 break;
1413 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1414 *params = mCaps.maxVertexImageUniforms;
1415 break;
1416 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1417 *params = mCaps.maxVertexShaderStorageBlocks;
1418 break;
1419 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1420 *params = mCaps.maxFragmentAtomicCounterBuffers;
1421 break;
1422 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1423 *params = mCaps.maxFragmentAtomicCounters;
1424 break;
1425 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1426 *params = mCaps.maxFragmentImageUniforms;
1427 break;
1428 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1429 *params = mCaps.maxFragmentShaderStorageBlocks;
1430 break;
1431 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1432 *params = mCaps.minProgramTextureGatherOffset;
1433 break;
1434 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1435 *params = mCaps.maxProgramTextureGatherOffset;
1436 break;
1437 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1438 *params = mCaps.maxComputeWorkGroupInvocations;
1439 break;
1440 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1441 *params = mCaps.maxComputeUniformBlocks;
1442 break;
1443 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1444 *params = mCaps.maxComputeTextureImageUnits;
1445 break;
1446 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1447 *params = mCaps.maxComputeSharedMemorySize;
1448 break;
1449 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1450 *params = mCaps.maxComputeUniformComponents;
1451 break;
1452 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1453 *params = mCaps.maxComputeAtomicCounterBuffers;
1454 break;
1455 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1456 *params = mCaps.maxComputeAtomicCounters;
1457 break;
1458 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1459 *params = mCaps.maxComputeImageUniforms;
1460 break;
1461 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1462 *params = mCaps.maxCombinedComputeUniformComponents;
1463 break;
1464 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1465 *params = mCaps.maxComputeShaderStorageBlocks;
1466 break;
1467 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1468 *params = mCaps.maxCombinedShaderOutputResources;
1469 break;
1470 case GL_MAX_UNIFORM_LOCATIONS:
1471 *params = mCaps.maxUniformLocations;
1472 break;
1473 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1474 *params = mCaps.maxAtomicCounterBufferBindings;
1475 break;
1476 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1477 *params = mCaps.maxAtomicCounterBufferSize;
1478 break;
1479 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1480 *params = mCaps.maxCombinedAtomicCounterBuffers;
1481 break;
1482 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1483 *params = mCaps.maxCombinedAtomicCounters;
1484 break;
1485 case GL_MAX_IMAGE_UNITS:
1486 *params = mCaps.maxImageUnits;
1487 break;
1488 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1489 *params = mCaps.maxCombinedImageUniforms;
1490 break;
1491 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1492 *params = mCaps.maxShaderStorageBufferBindings;
1493 break;
1494 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1495 *params = mCaps.maxCombinedShaderStorageBlocks;
1496 break;
1497 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1498 *params = mCaps.shaderStorageBufferOffsetAlignment;
1499 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001500 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001501 mGLState.getIntegerv(mState, pname, params);
1502 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001503 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001504}
1505
Jamie Madill893ab082014-05-16 16:56:10 -04001506void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001507{
Shannon Woods53a94a82014-06-24 15:20:36 -04001508 // Queries about context capabilities and maximums are answered by Context.
1509 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001510 switch (pname)
1511 {
1512 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001513 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001514 break;
1515 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001516 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001517 break;
1518 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001519 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001520 break;
1521 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001522 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001523 break;
1524 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001525 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001526 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001527
1528 // GL_EXT_disjoint_timer_query
1529 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001530 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001531 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001532
1533 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1534 *params = mCaps.maxShaderStorageBlockSize;
1535 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001536 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001537 UNREACHABLE();
1538 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001539 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001540}
1541
Geoff Lang70d0f492015-12-10 17:45:46 -05001542void Context::getPointerv(GLenum pname, void **params) const
1543{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001544 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001545}
1546
Martin Radev66fb8202016-07-28 11:45:20 +03001547void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001548{
Shannon Woods53a94a82014-06-24 15:20:36 -04001549 // Queries about context capabilities and maximums are answered by Context.
1550 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001551
1552 GLenum nativeType;
1553 unsigned int numParams;
1554 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1555 ASSERT(queryStatus);
1556
1557 if (nativeType == GL_INT)
1558 {
1559 switch (target)
1560 {
1561 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1562 ASSERT(index < 3u);
1563 *data = mCaps.maxComputeWorkGroupCount[index];
1564 break;
1565 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1566 ASSERT(index < 3u);
1567 *data = mCaps.maxComputeWorkGroupSize[index];
1568 break;
1569 default:
1570 mGLState.getIntegeri_v(target, index, data);
1571 }
1572 }
1573 else
1574 {
1575 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1576 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001577}
1578
Martin Radev66fb8202016-07-28 11:45:20 +03001579void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001580{
Shannon Woods53a94a82014-06-24 15:20:36 -04001581 // Queries about context capabilities and maximums are answered by Context.
1582 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001583
1584 GLenum nativeType;
1585 unsigned int numParams;
1586 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1587 ASSERT(queryStatus);
1588
1589 if (nativeType == GL_INT_64_ANGLEX)
1590 {
1591 mGLState.getInteger64i_v(target, index, data);
1592 }
1593 else
1594 {
1595 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1596 }
1597}
1598
1599void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1600{
1601 // Queries about context capabilities and maximums are answered by Context.
1602 // Queries about current GL state values are answered by State.
1603
1604 GLenum nativeType;
1605 unsigned int numParams;
1606 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1607 ASSERT(queryStatus);
1608
1609 if (nativeType == GL_BOOL)
1610 {
1611 mGLState.getBooleani_v(target, index, data);
1612 }
1613 else
1614 {
1615 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1616 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001617}
1618
Jamie Madill675fe712016-12-19 13:07:54 -05001619void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001620{
Jamie Madill1b94d432015-08-07 13:23:23 -04001621 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001622 auto error = mImplementation->drawArrays(mode, first, count);
1623 handleError(error);
1624 if (!error.isError())
1625 {
1626 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1627 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001628}
1629
Jamie Madill675fe712016-12-19 13:07:54 -05001630void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001631{
1632 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001633 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1634 handleError(error);
1635 if (!error.isError())
1636 {
1637 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1638 }
Geoff Langf6db0982015-08-25 13:04:00 -04001639}
1640
Jamie Madill675fe712016-12-19 13:07:54 -05001641void Context::drawElements(GLenum mode,
1642 GLsizei count,
1643 GLenum type,
1644 const GLvoid *indices,
1645 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001646{
Jamie Madill1b94d432015-08-07 13:23:23 -04001647 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001648 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001649}
1650
Jamie Madill675fe712016-12-19 13:07:54 -05001651void Context::drawElementsInstanced(GLenum mode,
1652 GLsizei count,
1653 GLenum type,
1654 const GLvoid *indices,
1655 GLsizei instances,
1656 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001657{
1658 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001659 handleError(
1660 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001661}
1662
Jamie Madill675fe712016-12-19 13:07:54 -05001663void Context::drawRangeElements(GLenum mode,
1664 GLuint start,
1665 GLuint end,
1666 GLsizei count,
1667 GLenum type,
1668 const GLvoid *indices,
1669 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001670{
1671 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001672 handleError(
1673 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001674}
1675
Jiajia Qind9671222016-11-29 16:30:31 +08001676void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1677{
1678 syncRendererState();
1679 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1680}
1681
1682void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1683{
1684 syncRendererState();
1685 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1686}
1687
Jamie Madill675fe712016-12-19 13:07:54 -05001688void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001689{
Jamie Madill675fe712016-12-19 13:07:54 -05001690 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001691}
1692
Jamie Madill675fe712016-12-19 13:07:54 -05001693void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001694{
Jamie Madill675fe712016-12-19 13:07:54 -05001695 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001696}
1697
Austin Kinross6ee1e782015-05-29 17:05:37 -07001698void Context::insertEventMarker(GLsizei length, const char *marker)
1699{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001700 ASSERT(mImplementation);
1701 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001702}
1703
1704void Context::pushGroupMarker(GLsizei length, const char *marker)
1705{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001706 ASSERT(mImplementation);
1707 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001708}
1709
1710void Context::popGroupMarker()
1711{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001712 ASSERT(mImplementation);
1713 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001714}
1715
Geoff Langd8605522016-04-13 10:19:12 -04001716void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1717{
1718 Program *programObject = getProgram(program);
1719 ASSERT(programObject);
1720
1721 programObject->bindUniformLocation(location, name);
1722}
1723
Sami Väisänena797e062016-05-12 15:23:40 +03001724void Context::setCoverageModulation(GLenum components)
1725{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001726 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001727}
1728
Sami Väisänene45e53b2016-05-25 10:36:04 +03001729void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1730{
1731 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1732}
1733
1734void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1735{
1736 GLfloat I[16];
1737 angle::Matrix<GLfloat>::setToIdentity(I);
1738
1739 mGLState.loadPathRenderingMatrix(matrixMode, I);
1740}
1741
1742void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1743{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001744 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001745 if (!pathObj)
1746 return;
1747
1748 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1749 syncRendererState();
1750
1751 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1752}
1753
1754void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1755{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001756 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001757 if (!pathObj)
1758 return;
1759
1760 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1761 syncRendererState();
1762
1763 mImplementation->stencilStrokePath(pathObj, reference, mask);
1764}
1765
1766void Context::coverFillPath(GLuint path, GLenum coverMode)
1767{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001768 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001769 if (!pathObj)
1770 return;
1771
1772 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1773 syncRendererState();
1774
1775 mImplementation->coverFillPath(pathObj, coverMode);
1776}
1777
1778void Context::coverStrokePath(GLuint path, GLenum coverMode)
1779{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001780 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001781 if (!pathObj)
1782 return;
1783
1784 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1785 syncRendererState();
1786
1787 mImplementation->coverStrokePath(pathObj, coverMode);
1788}
1789
1790void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1791{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001792 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001793 if (!pathObj)
1794 return;
1795
1796 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1797 syncRendererState();
1798
1799 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1800}
1801
1802void Context::stencilThenCoverStrokePath(GLuint path,
1803 GLint reference,
1804 GLuint mask,
1805 GLenum coverMode)
1806{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001807 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001808 if (!pathObj)
1809 return;
1810
1811 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1812 syncRendererState();
1813
1814 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1815}
1816
Sami Väisänend59ca052016-06-21 16:10:00 +03001817void Context::coverFillPathInstanced(GLsizei numPaths,
1818 GLenum pathNameType,
1819 const void *paths,
1820 GLuint pathBase,
1821 GLenum coverMode,
1822 GLenum transformType,
1823 const GLfloat *transformValues)
1824{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001825 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001826
1827 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1828 syncRendererState();
1829
1830 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1831}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001832
Sami Väisänend59ca052016-06-21 16:10:00 +03001833void Context::coverStrokePathInstanced(GLsizei numPaths,
1834 GLenum pathNameType,
1835 const void *paths,
1836 GLuint pathBase,
1837 GLenum coverMode,
1838 GLenum transformType,
1839 const GLfloat *transformValues)
1840{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001841 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001842
1843 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1844 syncRendererState();
1845
1846 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1847 transformValues);
1848}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001849
Sami Väisänend59ca052016-06-21 16:10:00 +03001850void Context::stencilFillPathInstanced(GLsizei numPaths,
1851 GLenum pathNameType,
1852 const void *paths,
1853 GLuint pathBase,
1854 GLenum fillMode,
1855 GLuint mask,
1856 GLenum transformType,
1857 const GLfloat *transformValues)
1858{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001859 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001860
1861 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1862 syncRendererState();
1863
1864 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1865 transformValues);
1866}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001867
Sami Väisänend59ca052016-06-21 16:10:00 +03001868void Context::stencilStrokePathInstanced(GLsizei numPaths,
1869 GLenum pathNameType,
1870 const void *paths,
1871 GLuint pathBase,
1872 GLint reference,
1873 GLuint mask,
1874 GLenum transformType,
1875 const GLfloat *transformValues)
1876{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001877 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001878
1879 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1880 syncRendererState();
1881
1882 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1883 transformValues);
1884}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001885
Sami Väisänend59ca052016-06-21 16:10:00 +03001886void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1887 GLenum pathNameType,
1888 const void *paths,
1889 GLuint pathBase,
1890 GLenum fillMode,
1891 GLuint mask,
1892 GLenum coverMode,
1893 GLenum transformType,
1894 const GLfloat *transformValues)
1895{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001896 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001897
1898 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1899 syncRendererState();
1900
1901 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1902 transformType, transformValues);
1903}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001904
Sami Väisänend59ca052016-06-21 16:10:00 +03001905void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1906 GLenum pathNameType,
1907 const void *paths,
1908 GLuint pathBase,
1909 GLint reference,
1910 GLuint mask,
1911 GLenum coverMode,
1912 GLenum transformType,
1913 const GLfloat *transformValues)
1914{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001915 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001916
1917 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1918 syncRendererState();
1919
1920 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1921 transformType, transformValues);
1922}
1923
Sami Väisänen46eaa942016-06-29 10:26:37 +03001924void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1925{
1926 auto *programObject = getProgram(program);
1927
1928 programObject->bindFragmentInputLocation(location, name);
1929}
1930
1931void Context::programPathFragmentInputGen(GLuint program,
1932 GLint location,
1933 GLenum genMode,
1934 GLint components,
1935 const GLfloat *coeffs)
1936{
1937 auto *programObject = getProgram(program);
1938
1939 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1940}
1941
Jamie Madill437fa652016-05-03 15:13:24 -04001942void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001943{
Geoff Langda5777c2014-07-11 09:52:58 -04001944 if (error.isError())
1945 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001946 GLenum code = error.getCode();
1947 mErrors.insert(code);
1948 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1949 {
1950 markContextLost();
1951 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001952
1953 if (!error.getMessage().empty())
1954 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001955 auto *debug = &mGLState.getDebug();
1956 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1957 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001958 }
Geoff Langda5777c2014-07-11 09:52:58 -04001959 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001960}
1961
1962// Get one of the recorded errors and clear its flag, if any.
1963// [OpenGL ES 2.0.24] section 2.5 page 13.
1964GLenum Context::getError()
1965{
Geoff Langda5777c2014-07-11 09:52:58 -04001966 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001967 {
Geoff Langda5777c2014-07-11 09:52:58 -04001968 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001969 }
Geoff Langda5777c2014-07-11 09:52:58 -04001970 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001971 {
Geoff Langda5777c2014-07-11 09:52:58 -04001972 GLenum error = *mErrors.begin();
1973 mErrors.erase(mErrors.begin());
1974 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001975 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001976}
1977
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001978// NOTE: this function should not assume that this context is current!
1979void Context::markContextLost()
1980{
1981 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001982 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001983 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001984 mContextLostForced = true;
1985 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001986 mContextLost = true;
1987}
1988
1989bool Context::isContextLost()
1990{
1991 return mContextLost;
1992}
1993
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001994GLenum Context::getResetStatus()
1995{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001996 // Even if the application doesn't want to know about resets, we want to know
1997 // as it will allow us to skip all the calls.
1998 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001999 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002000 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002001 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002002 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002003 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002004
2005 // EXT_robustness, section 2.6: If the reset notification behavior is
2006 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2007 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2008 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002009 }
2010
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002011 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2012 // status should be returned at least once, and GL_NO_ERROR should be returned
2013 // once the device has finished resetting.
2014 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002015 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002016 ASSERT(mResetStatus == GL_NO_ERROR);
2017 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002018
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002019 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002020 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002021 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002022 }
2023 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002024 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002025 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002026 // If markContextLost was used to mark the context lost then
2027 // assume that is not recoverable, and continue to report the
2028 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002029 mResetStatus = mImplementation->getResetStatus();
2030 }
Jamie Madill893ab082014-05-16 16:56:10 -04002031
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002032 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002033}
2034
2035bool Context::isResetNotificationEnabled()
2036{
2037 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2038}
2039
Corentin Walleze3b10e82015-05-20 11:06:25 -04002040const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002041{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002042 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002043}
2044
2045EGLenum Context::getClientType() const
2046{
2047 return mClientType;
2048}
2049
2050EGLenum Context::getRenderBuffer() const
2051{
Corentin Wallez37c39792015-08-20 14:19:46 -04002052 auto framebufferIt = mFramebufferMap.find(0);
2053 if (framebufferIt != mFramebufferMap.end())
2054 {
2055 const Framebuffer *framebuffer = framebufferIt->second;
2056 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2057
2058 ASSERT(backAttachment != nullptr);
2059 return backAttachment->getSurface()->getRenderBuffer();
2060 }
2061 else
2062 {
2063 return EGL_NONE;
2064 }
Régis Fénéon83107972015-02-05 12:57:44 +01002065}
2066
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002067VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002068{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002069 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002070 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2071 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002072 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002073 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2074
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002075 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002076 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002077
2078 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002079}
2080
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002081TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002082{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002083 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002084 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2085 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002086 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002087 transformFeedback =
2088 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002089 transformFeedback->addRef();
2090 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002091 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002092
2093 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002094}
2095
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002096Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2097{
2098 // Can be called from Bind without a prior call to Gen.
2099 auto framebufferIt = mFramebufferMap.find(framebuffer);
2100 bool neverCreated = framebufferIt == mFramebufferMap.end();
2101 if (neverCreated || framebufferIt->second == nullptr)
2102 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002103 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002104 if (neverCreated)
2105 {
2106 mFramebufferHandleAllocator.reserve(framebuffer);
2107 mFramebufferMap[framebuffer] = newFBO;
2108 return newFBO;
2109 }
2110
2111 framebufferIt->second = newFBO;
2112 }
2113
2114 return framebufferIt->second;
2115}
2116
Geoff Lang36167ab2015-12-07 10:27:14 -05002117bool Context::isVertexArrayGenerated(GLuint vertexArray)
2118{
Geoff Langf41a7152016-09-19 15:11:17 -04002119 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002120 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2121}
2122
2123bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2124{
Geoff Langf41a7152016-09-19 15:11:17 -04002125 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002126 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2127}
2128
Shannon Woods53a94a82014-06-24 15:20:36 -04002129void Context::detachTexture(GLuint texture)
2130{
2131 // Simple pass-through to State's detachTexture method, as textures do not require
2132 // allocation map management either here or in the resource manager at detach time.
2133 // Zero textures are held by the Context, and we don't attempt to request them from
2134 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002135 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002136}
2137
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002138void Context::detachBuffer(GLuint buffer)
2139{
Yuly Novikov5807a532015-12-03 13:01:22 -05002140 // Simple pass-through to State's detachBuffer method, since
2141 // only buffer attachments to container objects that are bound to the current context
2142 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002143
Yuly Novikov5807a532015-12-03 13:01:22 -05002144 // [OpenGL ES 3.2] section 5.1.2 page 45:
2145 // Attachments to unbound container objects, such as
2146 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2147 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002148 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002149}
2150
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002151void Context::detachFramebuffer(GLuint framebuffer)
2152{
Shannon Woods53a94a82014-06-24 15:20:36 -04002153 // Framebuffer detachment is handled by Context, because 0 is a valid
2154 // Framebuffer object, and a pointer to it must be passed from Context
2155 // to State at binding time.
2156
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002157 // [OpenGL ES 2.0.24] section 4.4 page 107:
2158 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2159 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2160
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002161 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002162 {
2163 bindReadFramebuffer(0);
2164 }
2165
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002166 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002167 {
2168 bindDrawFramebuffer(0);
2169 }
2170}
2171
2172void Context::detachRenderbuffer(GLuint renderbuffer)
2173{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002174 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002175}
2176
Jamie Madill57a89722013-07-02 11:57:03 -04002177void Context::detachVertexArray(GLuint vertexArray)
2178{
Jamie Madill77a72f62015-04-14 11:18:32 -04002179 // Vertex array detachment is handled by Context, because 0 is a valid
2180 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002181 // binding time.
2182
Jamie Madill57a89722013-07-02 11:57:03 -04002183 // [OpenGL ES 3.0.2] section 2.10 page 43:
2184 // If a vertex array object that is currently bound is deleted, the binding
2185 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002186 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002187 {
2188 bindVertexArray(0);
2189 }
2190}
2191
Geoff Langc8058452014-02-03 12:04:11 -05002192void Context::detachTransformFeedback(GLuint transformFeedback)
2193{
Corentin Walleza2257da2016-04-19 16:43:12 -04002194 // Transform feedback detachment is handled by Context, because 0 is a valid
2195 // transform feedback, and a pointer to it must be passed from Context to State at
2196 // binding time.
2197
2198 // The OpenGL specification doesn't mention what should happen when the currently bound
2199 // transform feedback object is deleted. Since it is a container object, we treat it like
2200 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002201 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002202 {
2203 bindTransformFeedback(0);
2204 }
Geoff Langc8058452014-02-03 12:04:11 -05002205}
2206
Jamie Madilldc356042013-07-19 16:36:57 -04002207void Context::detachSampler(GLuint sampler)
2208{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002209 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002210}
2211
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002212void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2213{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002214 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002215}
2216
Jamie Madille29d1672013-07-19 16:36:57 -04002217void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2218{
Geoff Langc1984ed2016-10-07 12:41:00 -04002219 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002220 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002221 SetSamplerParameteri(samplerObject, pname, param);
2222}
Jamie Madille29d1672013-07-19 16:36:57 -04002223
Geoff Langc1984ed2016-10-07 12:41:00 -04002224void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2225{
2226 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002227 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002228 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002229}
2230
2231void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2232{
Geoff Langc1984ed2016-10-07 12:41:00 -04002233 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002234 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002235 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002236}
2237
Geoff Langc1984ed2016-10-07 12:41:00 -04002238void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002239{
Geoff Langc1984ed2016-10-07 12:41:00 -04002240 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002241 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002242 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002243}
2244
Geoff Langc1984ed2016-10-07 12:41:00 -04002245void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002246{
Geoff Langc1984ed2016-10-07 12:41:00 -04002247 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002248 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002249 QuerySamplerParameteriv(samplerObject, pname, params);
2250}
Jamie Madill9675b802013-07-19 16:36:59 -04002251
Geoff Langc1984ed2016-10-07 12:41:00 -04002252void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2253{
2254 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002255 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002256 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002257}
2258
Olli Etuahof0fee072016-03-30 15:11:58 +03002259void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2260{
2261 gl::Program *programObject = getProgram(program);
2262 ASSERT(programObject != nullptr);
2263
2264 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2265 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2266}
2267
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002268void Context::initRendererString()
2269{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002270 std::ostringstream rendererString;
2271 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002272 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002273 rendererString << ")";
2274
Geoff Langcec35902014-04-16 10:52:36 -04002275 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002276}
2277
Geoff Langc339c4e2016-11-29 10:37:36 -05002278void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002279{
Geoff Langc339c4e2016-11-29 10:37:36 -05002280 const Version &clientVersion = getClientVersion();
2281
2282 std::ostringstream versionString;
2283 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2284 << ANGLE_VERSION_STRING << ")";
2285 mVersionString = MakeStaticString(versionString.str());
2286
2287 std::ostringstream shadingLanguageVersionString;
2288 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2289 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2290 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2291 << ")";
2292 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002293}
2294
Geoff Langcec35902014-04-16 10:52:36 -04002295void Context::initExtensionStrings()
2296{
Geoff Langc339c4e2016-11-29 10:37:36 -05002297 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2298 std::ostringstream combinedStringStream;
2299 std::copy(strings.begin(), strings.end(),
2300 std::ostream_iterator<const char *>(combinedStringStream, " "));
2301 return MakeStaticString(combinedStringStream.str());
2302 };
2303
2304 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002305 for (const auto &extensionString : mExtensions.getStrings())
2306 {
2307 mExtensionStrings.push_back(MakeStaticString(extensionString));
2308 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002309 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002310
Bryan Bernhart58806562017-01-05 13:09:31 -08002311 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2312
Geoff Langc339c4e2016-11-29 10:37:36 -05002313 mRequestableExtensionStrings.clear();
2314 for (const auto &extensionInfo : GetExtensionInfoMap())
2315 {
2316 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002317 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2318 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002319 {
2320 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2321 }
2322 }
2323 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002324}
2325
Geoff Langc339c4e2016-11-29 10:37:36 -05002326const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002327{
Geoff Langc339c4e2016-11-29 10:37:36 -05002328 switch (name)
2329 {
2330 case GL_VENDOR:
2331 return reinterpret_cast<const GLubyte *>("Google Inc.");
2332
2333 case GL_RENDERER:
2334 return reinterpret_cast<const GLubyte *>(mRendererString);
2335
2336 case GL_VERSION:
2337 return reinterpret_cast<const GLubyte *>(mVersionString);
2338
2339 case GL_SHADING_LANGUAGE_VERSION:
2340 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2341
2342 case GL_EXTENSIONS:
2343 return reinterpret_cast<const GLubyte *>(mExtensionString);
2344
2345 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2346 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2347
2348 default:
2349 UNREACHABLE();
2350 return nullptr;
2351 }
Geoff Langcec35902014-04-16 10:52:36 -04002352}
2353
Geoff Langc339c4e2016-11-29 10:37:36 -05002354const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002355{
Geoff Langc339c4e2016-11-29 10:37:36 -05002356 switch (name)
2357 {
2358 case GL_EXTENSIONS:
2359 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2360
2361 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2362 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2363
2364 default:
2365 UNREACHABLE();
2366 return nullptr;
2367 }
Geoff Langcec35902014-04-16 10:52:36 -04002368}
2369
2370size_t Context::getExtensionStringCount() const
2371{
2372 return mExtensionStrings.size();
2373}
2374
Geoff Langc339c4e2016-11-29 10:37:36 -05002375void Context::requestExtension(const char *name)
2376{
2377 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2378 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2379 const auto &extension = extensionInfos.at(name);
2380 ASSERT(extension.Requestable);
2381
2382 if (mExtensions.*(extension.ExtensionsMember))
2383 {
2384 // Extension already enabled
2385 return;
2386 }
2387
2388 mExtensions.*(extension.ExtensionsMember) = true;
2389 updateCaps();
2390 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002391
2392 // Re-create the compiler with the requested extensions enabled.
2393 SafeDelete(mCompiler);
2394 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002395}
2396
2397size_t Context::getRequestableExtensionStringCount() const
2398{
2399 return mRequestableExtensionStrings.size();
2400}
2401
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002402void Context::beginTransformFeedback(GLenum primitiveMode)
2403{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002404 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002405 ASSERT(transformFeedback != nullptr);
2406 ASSERT(!transformFeedback->isPaused());
2407
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002408 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002409}
2410
2411bool Context::hasActiveTransformFeedback(GLuint program) const
2412{
2413 for (auto pair : mTransformFeedbackMap)
2414 {
2415 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2416 {
2417 return true;
2418 }
2419 }
2420 return false;
2421}
2422
Geoff Langc287ea62016-09-16 14:46:51 -04002423void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002424{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002425 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002426
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002427 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002428
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002429 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002430
Geoff Langeb66a6e2016-10-31 13:06:12 -04002431 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002432 {
2433 // Disable ES3+ extensions
2434 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002435 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002436 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002437 }
2438
Geoff Langeb66a6e2016-10-31 13:06:12 -04002439 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002440 {
2441 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2442 //mExtensions.sRGB = false;
2443 }
2444
Jamie Madill00ed7a12016-05-19 13:13:38 -04002445 // Some extensions are always available because they are implemented in the GL layer.
2446 mExtensions.bindUniformLocation = true;
2447 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002448 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002449 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002450
2451 // Enable the no error extension if the context was created with the flag.
2452 mExtensions.noError = mSkipValidation;
2453
Corentin Wallezccab69d2017-01-27 16:57:15 -05002454 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
2455 mExtensions.surfacelessContext = true;
2456
Geoff Lang70d0f492015-12-10 17:45:46 -05002457 // Explicitly enable GL_KHR_debug
2458 mExtensions.debug = true;
2459 mExtensions.maxDebugMessageLength = 1024;
2460 mExtensions.maxDebugLoggedMessages = 1024;
2461 mExtensions.maxDebugGroupStackDepth = 1024;
2462 mExtensions.maxLabelLength = 1024;
2463
Geoff Langff5b2d52016-09-07 11:32:23 -04002464 // Explicitly enable GL_ANGLE_robust_client_memory
2465 mExtensions.robustClientMemory = true;
2466
Geoff Lang301d1612014-07-09 10:34:37 -04002467 // Apply implementation limits
2468 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002469 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2470 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2471
2472 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002473
Geoff Langc287ea62016-09-16 14:46:51 -04002474 // WebGL compatibility
2475 mExtensions.webglCompatibility = webGLContext;
2476 for (const auto &extensionInfo : GetExtensionInfoMap())
2477 {
2478 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002479 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002480 {
2481 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2482 }
2483 }
2484
2485 // Generate texture caps
2486 updateCaps();
2487}
2488
2489void Context::updateCaps()
2490{
Geoff Lang900013c2014-07-07 11:32:19 -04002491 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002492 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002493
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002494 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002495 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2496 {
2497 GLenum format = i->first;
2498 TextureCaps formatCaps = i->second;
2499
Geoff Lang5d601382014-07-22 15:14:06 -04002500 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002501
Geoff Lang0d8b7242015-09-09 14:56:53 -04002502 // Update the format caps based on the client version and extensions.
2503 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2504 // ES3.
2505 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002506 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002507 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002508 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002509 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002510 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002511
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002512 // OpenGL ES does not support multisampling with non-rendererable formats
2513 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2514 if (!formatInfo.renderSupport ||
2515 (getClientVersion() < ES_3_1 &&
2516 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002517 {
Geoff Langd87878e2014-09-19 15:42:59 -04002518 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002519 }
Geoff Langd87878e2014-09-19 15:42:59 -04002520
2521 if (formatCaps.texturable && formatInfo.compressed)
2522 {
2523 mCaps.compressedTextureFormats.push_back(format);
2524 }
2525
2526 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002527 }
2528}
2529
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002530void Context::initWorkarounds()
2531{
2532 // Lose the context upon out of memory error if the application is
2533 // expecting to watch for those events.
2534 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2535}
2536
Jamie Madill1b94d432015-08-07 13:23:23 -04002537void Context::syncRendererState()
2538{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002539 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2540 mImplementation->syncState(mGLState, dirtyBits);
2541 mGLState.clearDirtyBits();
2542 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002543}
2544
Jamie Madillad9f24e2016-02-12 09:27:24 -05002545void Context::syncRendererState(const State::DirtyBits &bitMask,
2546 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002547{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002548 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2549 mImplementation->syncState(mGLState, dirtyBits);
2550 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002551
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002552 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002553}
Jamie Madillc29968b2016-01-20 11:17:23 -05002554
2555void Context::blitFramebuffer(GLint srcX0,
2556 GLint srcY0,
2557 GLint srcX1,
2558 GLint srcY1,
2559 GLint dstX0,
2560 GLint dstY0,
2561 GLint dstX1,
2562 GLint dstY1,
2563 GLbitfield mask,
2564 GLenum filter)
2565{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002566 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002567 ASSERT(drawFramebuffer);
2568
2569 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2570 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2571
Jamie Madillad9f24e2016-02-12 09:27:24 -05002572 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002573
Jamie Madill8415b5f2016-04-26 13:41:39 -04002574 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002575}
Jamie Madillc29968b2016-01-20 11:17:23 -05002576
2577void Context::clear(GLbitfield mask)
2578{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002579 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002580 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002581}
2582
2583void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2584{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002585 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002586 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2587 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002588}
2589
2590void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2591{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002592 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002593 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2594 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002595}
2596
2597void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2598{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002599 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002600 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2601 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002602}
2603
2604void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2605{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002606 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002607 ASSERT(framebufferObject);
2608
2609 // If a buffer is not present, the clear has no effect
2610 if (framebufferObject->getDepthbuffer() == nullptr &&
2611 framebufferObject->getStencilbuffer() == nullptr)
2612 {
2613 return;
2614 }
2615
Jamie Madillad9f24e2016-02-12 09:27:24 -05002616 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002617 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2618 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002619}
2620
2621void Context::readPixels(GLint x,
2622 GLint y,
2623 GLsizei width,
2624 GLsizei height,
2625 GLenum format,
2626 GLenum type,
2627 GLvoid *pixels)
2628{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002629 if (width == 0 || height == 0)
2630 {
2631 return;
2632 }
2633
Jamie Madillad9f24e2016-02-12 09:27:24 -05002634 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002635
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002636 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002637 ASSERT(framebufferObject);
2638
2639 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002640 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002641}
2642
2643void Context::copyTexImage2D(GLenum target,
2644 GLint level,
2645 GLenum internalformat,
2646 GLint x,
2647 GLint y,
2648 GLsizei width,
2649 GLsizei height,
2650 GLint border)
2651{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002652 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002653 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002654
Jamie Madillc29968b2016-01-20 11:17:23 -05002655 Rectangle sourceArea(x, y, width, height);
2656
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002657 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002658 Texture *texture =
2659 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002660 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002661}
2662
2663void Context::copyTexSubImage2D(GLenum target,
2664 GLint level,
2665 GLint xoffset,
2666 GLint yoffset,
2667 GLint x,
2668 GLint y,
2669 GLsizei width,
2670 GLsizei height)
2671{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002672 if (width == 0 || height == 0)
2673 {
2674 return;
2675 }
2676
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002677 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002678 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002679
Jamie Madillc29968b2016-01-20 11:17:23 -05002680 Offset destOffset(xoffset, yoffset, 0);
2681 Rectangle sourceArea(x, y, width, height);
2682
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002683 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002684 Texture *texture =
2685 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002686 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002687}
2688
2689void Context::copyTexSubImage3D(GLenum target,
2690 GLint level,
2691 GLint xoffset,
2692 GLint yoffset,
2693 GLint zoffset,
2694 GLint x,
2695 GLint y,
2696 GLsizei width,
2697 GLsizei height)
2698{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002699 if (width == 0 || height == 0)
2700 {
2701 return;
2702 }
2703
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002704 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002705 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002706
Jamie Madillc29968b2016-01-20 11:17:23 -05002707 Offset destOffset(xoffset, yoffset, zoffset);
2708 Rectangle sourceArea(x, y, width, height);
2709
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002710 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002711 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002712 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002713}
2714
2715void Context::framebufferTexture2D(GLenum target,
2716 GLenum attachment,
2717 GLenum textarget,
2718 GLuint texture,
2719 GLint level)
2720{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002721 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002722 ASSERT(framebuffer);
2723
2724 if (texture != 0)
2725 {
2726 Texture *textureObj = getTexture(texture);
2727
2728 ImageIndex index = ImageIndex::MakeInvalid();
2729
2730 if (textarget == GL_TEXTURE_2D)
2731 {
2732 index = ImageIndex::Make2D(level);
2733 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002734 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2735 {
2736 ASSERT(level == 0);
2737 index = ImageIndex::Make2DMultisample();
2738 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002739 else
2740 {
2741 ASSERT(IsCubeMapTextureTarget(textarget));
2742 index = ImageIndex::MakeCube(textarget, level);
2743 }
2744
2745 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2746 }
2747 else
2748 {
2749 framebuffer->resetAttachment(attachment);
2750 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002751
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002752 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002753}
2754
2755void Context::framebufferRenderbuffer(GLenum target,
2756 GLenum attachment,
2757 GLenum renderbuffertarget,
2758 GLuint renderbuffer)
2759{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002760 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002761 ASSERT(framebuffer);
2762
2763 if (renderbuffer != 0)
2764 {
2765 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2766 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2767 renderbufferObject);
2768 }
2769 else
2770 {
2771 framebuffer->resetAttachment(attachment);
2772 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002773
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002774 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002775}
2776
2777void Context::framebufferTextureLayer(GLenum target,
2778 GLenum attachment,
2779 GLuint texture,
2780 GLint level,
2781 GLint layer)
2782{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002783 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002784 ASSERT(framebuffer);
2785
2786 if (texture != 0)
2787 {
2788 Texture *textureObject = getTexture(texture);
2789
2790 ImageIndex index = ImageIndex::MakeInvalid();
2791
2792 if (textureObject->getTarget() == GL_TEXTURE_3D)
2793 {
2794 index = ImageIndex::Make3D(level, layer);
2795 }
2796 else
2797 {
2798 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2799 index = ImageIndex::Make2DArray(level, layer);
2800 }
2801
2802 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2803 }
2804 else
2805 {
2806 framebuffer->resetAttachment(attachment);
2807 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002808
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002809 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002810}
2811
2812void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2813{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002814 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002815 ASSERT(framebuffer);
2816 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002817 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002818}
2819
2820void Context::readBuffer(GLenum mode)
2821{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002822 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002823 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002824 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002825}
2826
2827void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2828{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002829 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002830 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002831
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002832 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002833 ASSERT(framebuffer);
2834
2835 // The specification isn't clear what should be done when the framebuffer isn't complete.
2836 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002837 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002838}
2839
2840void Context::invalidateFramebuffer(GLenum target,
2841 GLsizei numAttachments,
2842 const GLenum *attachments)
2843{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002844 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002845 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002846
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002847 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002848 ASSERT(framebuffer);
2849
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002850 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002851 {
Jamie Madill437fa652016-05-03 15:13:24 -04002852 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002853 }
Jamie Madill437fa652016-05-03 15:13:24 -04002854
2855 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002856}
2857
2858void Context::invalidateSubFramebuffer(GLenum target,
2859 GLsizei numAttachments,
2860 const GLenum *attachments,
2861 GLint x,
2862 GLint y,
2863 GLsizei width,
2864 GLsizei height)
2865{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002866 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002867 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002868
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002869 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002870 ASSERT(framebuffer);
2871
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002872 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002873 {
Jamie Madill437fa652016-05-03 15:13:24 -04002874 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002875 }
Jamie Madill437fa652016-05-03 15:13:24 -04002876
2877 Rectangle area(x, y, width, height);
2878 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002879}
2880
Jamie Madill73a84962016-02-12 09:27:23 -05002881void Context::texImage2D(GLenum target,
2882 GLint level,
2883 GLint internalformat,
2884 GLsizei width,
2885 GLsizei height,
2886 GLint border,
2887 GLenum format,
2888 GLenum type,
2889 const GLvoid *pixels)
2890{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002891 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002892
2893 Extents size(width, height, 1);
2894 Texture *texture =
2895 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002896 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002897 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002898}
2899
2900void Context::texImage3D(GLenum target,
2901 GLint level,
2902 GLint internalformat,
2903 GLsizei width,
2904 GLsizei height,
2905 GLsizei depth,
2906 GLint border,
2907 GLenum format,
2908 GLenum type,
2909 const GLvoid *pixels)
2910{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002911 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002912
2913 Extents size(width, height, depth);
2914 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002915 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002916 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002917}
2918
2919void Context::texSubImage2D(GLenum target,
2920 GLint level,
2921 GLint xoffset,
2922 GLint yoffset,
2923 GLsizei width,
2924 GLsizei height,
2925 GLenum format,
2926 GLenum type,
2927 const GLvoid *pixels)
2928{
2929 // Zero sized uploads are valid but no-ops
2930 if (width == 0 || height == 0)
2931 {
2932 return;
2933 }
2934
Jamie Madillad9f24e2016-02-12 09:27:24 -05002935 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002936
2937 Box area(xoffset, yoffset, 0, width, height, 1);
2938 Texture *texture =
2939 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002940 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002941 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002942}
2943
2944void Context::texSubImage3D(GLenum target,
2945 GLint level,
2946 GLint xoffset,
2947 GLint yoffset,
2948 GLint zoffset,
2949 GLsizei width,
2950 GLsizei height,
2951 GLsizei depth,
2952 GLenum format,
2953 GLenum type,
2954 const GLvoid *pixels)
2955{
2956 // Zero sized uploads are valid but no-ops
2957 if (width == 0 || height == 0 || depth == 0)
2958 {
2959 return;
2960 }
2961
Jamie Madillad9f24e2016-02-12 09:27:24 -05002962 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002963
2964 Box area(xoffset, yoffset, zoffset, width, height, depth);
2965 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002966 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002967 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002968}
2969
2970void Context::compressedTexImage2D(GLenum target,
2971 GLint level,
2972 GLenum internalformat,
2973 GLsizei width,
2974 GLsizei height,
2975 GLint border,
2976 GLsizei imageSize,
2977 const GLvoid *data)
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 Madilldfde6ab2016-06-09 07:07:18 -07002984 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2985 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002986 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002987}
2988
2989void Context::compressedTexImage3D(GLenum target,
2990 GLint level,
2991 GLenum internalformat,
2992 GLsizei width,
2993 GLsizei height,
2994 GLsizei depth,
2995 GLint border,
2996 GLsizei imageSize,
2997 const GLvoid *data)
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 Madilldfde6ab2016-06-09 07:07:18 -07003003 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
3004 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003005 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003006}
3007
3008void Context::compressedTexSubImage2D(GLenum target,
3009 GLint level,
3010 GLint xoffset,
3011 GLint yoffset,
3012 GLsizei width,
3013 GLsizei height,
3014 GLenum format,
3015 GLsizei imageSize,
3016 const GLvoid *data)
3017{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003018 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003019
3020 Box area(xoffset, yoffset, 0, width, height, 1);
3021 Texture *texture =
3022 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003023 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3024 format, imageSize,
3025 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003026}
3027
3028void Context::compressedTexSubImage3D(GLenum target,
3029 GLint level,
3030 GLint xoffset,
3031 GLint yoffset,
3032 GLint zoffset,
3033 GLsizei width,
3034 GLsizei height,
3035 GLsizei depth,
3036 GLenum format,
3037 GLsizei imageSize,
3038 const GLvoid *data)
3039{
3040 // Zero sized uploads are valid but no-ops
3041 if (width == 0 || height == 0)
3042 {
3043 return;
3044 }
3045
Jamie Madillad9f24e2016-02-12 09:27:24 -05003046 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003047
3048 Box area(xoffset, yoffset, zoffset, width, height, depth);
3049 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003050 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3051 format, imageSize,
3052 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003053}
3054
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003055void Context::generateMipmap(GLenum target)
3056{
3057 Texture *texture = getTargetTexture(target);
3058 handleError(texture->generateMipmap());
3059}
3060
Geoff Lang97073d12016-04-20 10:42:34 -07003061void Context::copyTextureCHROMIUM(GLuint sourceId,
3062 GLuint destId,
3063 GLint internalFormat,
3064 GLenum destType,
3065 GLboolean unpackFlipY,
3066 GLboolean unpackPremultiplyAlpha,
3067 GLboolean unpackUnmultiplyAlpha)
3068{
3069 syncStateForTexImage();
3070
3071 gl::Texture *sourceTexture = getTexture(sourceId);
3072 gl::Texture *destTexture = getTexture(destId);
3073 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3074 unpackPremultiplyAlpha == GL_TRUE,
3075 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3076}
3077
3078void Context::copySubTextureCHROMIUM(GLuint sourceId,
3079 GLuint destId,
3080 GLint xoffset,
3081 GLint yoffset,
3082 GLint x,
3083 GLint y,
3084 GLsizei width,
3085 GLsizei height,
3086 GLboolean unpackFlipY,
3087 GLboolean unpackPremultiplyAlpha,
3088 GLboolean unpackUnmultiplyAlpha)
3089{
3090 // Zero sized copies are valid but no-ops
3091 if (width == 0 || height == 0)
3092 {
3093 return;
3094 }
3095
3096 syncStateForTexImage();
3097
3098 gl::Texture *sourceTexture = getTexture(sourceId);
3099 gl::Texture *destTexture = getTexture(destId);
3100 Offset offset(xoffset, yoffset, 0);
3101 Rectangle area(x, y, width, height);
3102 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3103 unpackPremultiplyAlpha == GL_TRUE,
3104 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3105}
3106
Geoff Lang47110bf2016-04-20 11:13:22 -07003107void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3108{
3109 syncStateForTexImage();
3110
3111 gl::Texture *sourceTexture = getTexture(sourceId);
3112 gl::Texture *destTexture = getTexture(destId);
3113 handleError(destTexture->copyCompressedTexture(sourceTexture));
3114}
3115
Geoff Lang496c02d2016-10-20 11:38:11 -07003116void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003117{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003118 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003119 ASSERT(buffer);
3120
Geoff Lang496c02d2016-10-20 11:38:11 -07003121 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003122}
3123
3124GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3125{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003126 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003127 ASSERT(buffer);
3128
3129 Error error = buffer->map(access);
3130 if (error.isError())
3131 {
Jamie Madill437fa652016-05-03 15:13:24 -04003132 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003133 return nullptr;
3134 }
3135
3136 return buffer->getMapPointer();
3137}
3138
3139GLboolean Context::unmapBuffer(GLenum target)
3140{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003141 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003142 ASSERT(buffer);
3143
3144 GLboolean result;
3145 Error error = buffer->unmap(&result);
3146 if (error.isError())
3147 {
Jamie Madill437fa652016-05-03 15:13:24 -04003148 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003149 return GL_FALSE;
3150 }
3151
3152 return result;
3153}
3154
3155GLvoid *Context::mapBufferRange(GLenum target,
3156 GLintptr offset,
3157 GLsizeiptr length,
3158 GLbitfield access)
3159{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003160 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003161 ASSERT(buffer);
3162
3163 Error error = buffer->mapRange(offset, length, access);
3164 if (error.isError())
3165 {
Jamie Madill437fa652016-05-03 15:13:24 -04003166 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003167 return nullptr;
3168 }
3169
3170 return buffer->getMapPointer();
3171}
3172
3173void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3174{
3175 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3176}
3177
Jamie Madillad9f24e2016-02-12 09:27:24 -05003178void Context::syncStateForReadPixels()
3179{
3180 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3181}
3182
3183void Context::syncStateForTexImage()
3184{
3185 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3186}
3187
3188void Context::syncStateForClear()
3189{
3190 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3191}
3192
3193void Context::syncStateForBlit()
3194{
3195 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3196}
3197
Jamie Madillc20ab272016-06-09 07:20:46 -07003198void Context::activeTexture(GLenum texture)
3199{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003200 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003201}
3202
3203void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3204{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003205 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003206}
3207
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003208void Context::blendEquation(GLenum mode)
3209{
3210 mGLState.setBlendEquation(mode, mode);
3211}
3212
Jamie Madillc20ab272016-06-09 07:20:46 -07003213void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3214{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003215 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003216}
3217
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003218void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3219{
3220 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3221}
3222
Jamie Madillc20ab272016-06-09 07:20:46 -07003223void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3224{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003225 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003226}
3227
3228void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3229{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003230 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003231}
3232
3233void Context::clearDepthf(GLclampf depth)
3234{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003235 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003236}
3237
3238void Context::clearStencil(GLint s)
3239{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003240 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003241}
3242
3243void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3244{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003245 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003246}
3247
3248void Context::cullFace(GLenum mode)
3249{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003250 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003251}
3252
3253void Context::depthFunc(GLenum func)
3254{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003255 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003256}
3257
3258void Context::depthMask(GLboolean flag)
3259{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003260 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003261}
3262
3263void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3264{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003265 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003266}
3267
3268void Context::disable(GLenum cap)
3269{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003270 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003271}
3272
3273void Context::disableVertexAttribArray(GLuint index)
3274{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003275 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003276}
3277
3278void Context::enable(GLenum cap)
3279{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003280 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003281}
3282
3283void Context::enableVertexAttribArray(GLuint index)
3284{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003285 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003286}
3287
3288void Context::frontFace(GLenum mode)
3289{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003290 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003291}
3292
3293void Context::hint(GLenum target, GLenum mode)
3294{
3295 switch (target)
3296 {
3297 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003298 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003299 break;
3300
3301 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003302 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003303 break;
3304
3305 default:
3306 UNREACHABLE();
3307 return;
3308 }
3309}
3310
3311void Context::lineWidth(GLfloat width)
3312{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003313 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003314}
3315
3316void Context::pixelStorei(GLenum pname, GLint param)
3317{
3318 switch (pname)
3319 {
3320 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003321 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003322 break;
3323
3324 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003325 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003326 break;
3327
3328 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003329 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003330 break;
3331
3332 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003333 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335 break;
3336
3337 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003338 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340 break;
3341
3342 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003343 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345 break;
3346
3347 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003348 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003350 break;
3351
3352 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003353 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003355 break;
3356
3357 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003358 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003359 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003360 break;
3361
3362 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003363 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365 break;
3366
3367 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003368 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370 break;
3371
3372 default:
3373 UNREACHABLE();
3374 return;
3375 }
3376}
3377
3378void Context::polygonOffset(GLfloat factor, GLfloat units)
3379{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003380 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003381}
3382
3383void Context::sampleCoverage(GLclampf value, GLboolean invert)
3384{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003385 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003386}
3387
3388void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3389{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003390 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003391}
3392
3393void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3394{
3395 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3396 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003397 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003398 }
3399
3400 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3401 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003402 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003403 }
3404}
3405
3406void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3407{
3408 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3409 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003410 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003411 }
3412
3413 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3414 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003415 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003416 }
3417}
3418
3419void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3420{
3421 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3422 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003423 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003424 }
3425
3426 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3427 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003428 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003429 }
3430}
3431
3432void Context::vertexAttrib1f(GLuint index, GLfloat x)
3433{
3434 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003435 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003436}
3437
3438void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3439{
3440 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003441 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003442}
3443
3444void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3445{
3446 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003447 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003448}
3449
3450void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3451{
3452 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003453 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003454}
3455
3456void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3457{
3458 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003460}
3461
3462void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3463{
3464 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003466}
3467
3468void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3469{
3470 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003471 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003472}
3473
3474void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3475{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003476 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003477}
3478
3479void Context::vertexAttribPointer(GLuint index,
3480 GLint size,
3481 GLenum type,
3482 GLboolean normalized,
3483 GLsizei stride,
3484 const GLvoid *ptr)
3485{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003486 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3487 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003488}
3489
3490void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3491{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003492 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003493}
3494
3495void Context::vertexAttribIPointer(GLuint index,
3496 GLint size,
3497 GLenum type,
3498 GLsizei stride,
3499 const GLvoid *pointer)
3500{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003501 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3502 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003503}
3504
3505void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3506{
3507 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003509}
3510
3511void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3512{
3513 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003514 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003515}
3516
3517void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3518{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003519 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003520}
3521
3522void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3523{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003524 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003525}
3526
3527void Context::debugMessageControl(GLenum source,
3528 GLenum type,
3529 GLenum severity,
3530 GLsizei count,
3531 const GLuint *ids,
3532 GLboolean enabled)
3533{
3534 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003535 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3536 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003537}
3538
3539void Context::debugMessageInsert(GLenum source,
3540 GLenum type,
3541 GLuint id,
3542 GLenum severity,
3543 GLsizei length,
3544 const GLchar *buf)
3545{
3546 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003547 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003548}
3549
3550void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3551{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003552 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003553}
3554
3555GLuint Context::getDebugMessageLog(GLuint count,
3556 GLsizei bufSize,
3557 GLenum *sources,
3558 GLenum *types,
3559 GLuint *ids,
3560 GLenum *severities,
3561 GLsizei *lengths,
3562 GLchar *messageLog)
3563{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003564 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3565 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003566}
3567
3568void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3569{
3570 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003571 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003572}
3573
3574void Context::popDebugGroup()
3575{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003576 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003577}
3578
Jamie Madill29639852016-09-02 15:00:09 -04003579void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3580{
3581 Buffer *buffer = mGLState.getTargetBuffer(target);
3582 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003583 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003584}
3585
3586void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3587{
3588 if (data == nullptr)
3589 {
3590 return;
3591 }
3592
3593 Buffer *buffer = mGLState.getTargetBuffer(target);
3594 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003595 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003596}
3597
Jamie Madillef300b12016-10-07 15:12:09 -04003598void Context::attachShader(GLuint program, GLuint shader)
3599{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003600 auto programObject = mState.mShaderPrograms->getProgram(program);
3601 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003602 ASSERT(programObject && shaderObject);
3603 programObject->attachShader(shaderObject);
3604}
3605
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003606const Workarounds &Context::getWorkarounds() const
3607{
3608 return mWorkarounds;
3609}
3610
Jamie Madillb0817d12016-11-01 15:48:31 -04003611void Context::copyBufferSubData(GLenum readTarget,
3612 GLenum writeTarget,
3613 GLintptr readOffset,
3614 GLintptr writeOffset,
3615 GLsizeiptr size)
3616{
3617 // if size is zero, the copy is a successful no-op
3618 if (size == 0)
3619 {
3620 return;
3621 }
3622
3623 // TODO(jmadill): cache these.
3624 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3625 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3626
3627 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3628}
3629
Jamie Madill01a80ee2016-11-07 12:06:18 -05003630void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3631{
3632 Program *programObject = getProgram(program);
3633 // TODO(jmadill): Re-use this from the validation if possible.
3634 ASSERT(programObject);
3635 programObject->bindAttributeLocation(index, name);
3636}
3637
3638void Context::bindBuffer(GLenum target, GLuint buffer)
3639{
3640 switch (target)
3641 {
3642 case GL_ARRAY_BUFFER:
3643 bindArrayBuffer(buffer);
3644 break;
3645 case GL_ELEMENT_ARRAY_BUFFER:
3646 bindElementArrayBuffer(buffer);
3647 break;
3648 case GL_COPY_READ_BUFFER:
3649 bindCopyReadBuffer(buffer);
3650 break;
3651 case GL_COPY_WRITE_BUFFER:
3652 bindCopyWriteBuffer(buffer);
3653 break;
3654 case GL_PIXEL_PACK_BUFFER:
3655 bindPixelPackBuffer(buffer);
3656 break;
3657 case GL_PIXEL_UNPACK_BUFFER:
3658 bindPixelUnpackBuffer(buffer);
3659 break;
3660 case GL_UNIFORM_BUFFER:
3661 bindGenericUniformBuffer(buffer);
3662 break;
3663 case GL_TRANSFORM_FEEDBACK_BUFFER:
3664 bindGenericTransformFeedbackBuffer(buffer);
3665 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003666 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003667 if (buffer != 0)
3668 {
3669 // Binding buffers to this binding point is not implemented yet.
3670 UNIMPLEMENTED();
3671 }
Geoff Lang3b573612016-10-31 14:08:10 -04003672 break;
3673 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003674 if (buffer != 0)
3675 {
3676 // Binding buffers to this binding point is not implemented yet.
3677 UNIMPLEMENTED();
3678 }
Geoff Lang3b573612016-10-31 14:08:10 -04003679 break;
3680 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003681 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003682 break;
3683 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003684 if (buffer != 0)
3685 {
3686 // Binding buffers to this binding point is not implemented yet.
3687 UNIMPLEMENTED();
3688 }
Geoff Lang3b573612016-10-31 14:08:10 -04003689 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003690
3691 default:
3692 UNREACHABLE();
3693 break;
3694 }
3695}
3696
3697void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3698{
3699 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3700 {
3701 bindReadFramebuffer(framebuffer);
3702 }
3703
3704 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3705 {
3706 bindDrawFramebuffer(framebuffer);
3707 }
3708}
3709
3710void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3711{
3712 ASSERT(target == GL_RENDERBUFFER);
3713 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003714 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003715 mGLState.setRenderbufferBinding(object);
3716}
3717
JiangYizhoubddc46b2016-12-09 09:50:51 +08003718void Context::texStorage2DMultisample(GLenum target,
3719 GLsizei samples,
3720 GLenum internalformat,
3721 GLsizei width,
3722 GLsizei height,
3723 GLboolean fixedsamplelocations)
3724{
3725 Extents size(width, height, 1);
3726 Texture *texture = getTargetTexture(target);
3727 handleError(texture->setStorageMultisample(target, samples, internalformat, size,
3728 fixedsamplelocations));
3729}
3730
3731void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3732{
3733 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3734 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3735
3736 switch (pname)
3737 {
3738 case GL_SAMPLE_POSITION:
3739 handleError(framebuffer->getSamplePosition(index, val));
3740 break;
3741 default:
3742 UNREACHABLE();
3743 }
3744}
3745
Jamie Madillc29968b2016-01-20 11:17:23 -05003746} // namespace gl