blob: 6f04a4ce0e245bb044b9d0f16b409a7ec45226e2 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050029#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/ResourceManager.h"
31#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050032#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050033#include "libANGLE/Texture.h"
34#include "libANGLE/TransformFeedback.h"
35#include "libANGLE/VertexArray.h"
36#include "libANGLE/formatutils.h"
37#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070038#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040039#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040040#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030041#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040042#include "libANGLE/queryutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000043
Geoff Langf6db0982015-08-25 13:04:00 -040044namespace
45{
46
Ian Ewell3ffd78b2016-01-22 16:09:42 -050047template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050048std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030049 GLsizei numPaths,
50 const void *paths,
51 GLuint pathBase)
52{
53 std::vector<gl::Path *> ret;
54 ret.reserve(numPaths);
55
56 const auto *nameArray = static_cast<const T *>(paths);
57
58 for (GLsizei i = 0; i < numPaths; ++i)
59 {
60 const GLuint pathName = nameArray[i] + pathBase;
61
62 ret.push_back(resourceManager.getPath(pathName));
63 }
64
65 return ret;
66}
67
Geoff Lang4ddf5af2016-12-01 14:30:44 -050068std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030069 GLsizei numPaths,
70 GLenum pathNameType,
71 const void *paths,
72 GLuint pathBase)
73{
74 switch (pathNameType)
75 {
76 case GL_UNSIGNED_BYTE:
77 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
78
79 case GL_BYTE:
80 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
81
82 case GL_UNSIGNED_SHORT:
83 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_SHORT:
86 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_INT:
89 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_INT:
92 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
93 }
94
95 UNREACHABLE();
96 return std::vector<gl::Path *>();
97}
98
99template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400100gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500101{
Geoff Lang2186c382016-10-14 10:54:54 -0400102 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500103
104 switch (pname)
105 {
106 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400107 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500108 case GL_QUERY_RESULT_AVAILABLE_EXT:
109 {
110 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400111 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500112 if (!error.isError())
113 {
Geoff Lang2186c382016-10-14 10:54:54 -0400114 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500115 }
116 return error;
117 }
118 default:
119 UNREACHABLE();
120 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
121 }
122}
123
Geoff Langf6db0982015-08-25 13:04:00 -0400124void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
125{
Geoff Lang1a683462015-09-29 15:09:59 -0400126 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400127 {
128 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
129 tfBufferIndex++)
130 {
131 const OffsetBindingPointer<gl::Buffer> &buffer =
132 transformFeedback->getIndexedBuffer(tfBufferIndex);
133 if (buffer.get() != nullptr)
134 {
135 buffer->onTransformFeedback();
136 }
137 }
138 }
139}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140
141// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300142EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500143{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400144 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500145}
146
Martin Radev1be913c2016-07-11 17:59:16 +0300147EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
148{
149 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
150}
151
Geoff Langeb66a6e2016-10-31 13:06:12 -0400152gl::Version GetClientVersion(const egl::AttributeMap &attribs)
153{
154 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
155}
156
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500157GLenum GetResetStrategy(const egl::AttributeMap &attribs)
158{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400159 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
160 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500161 switch (attrib)
162 {
163 case EGL_NO_RESET_NOTIFICATION:
164 return GL_NO_RESET_NOTIFICATION_EXT;
165 case EGL_LOSE_CONTEXT_ON_RESET:
166 return GL_LOSE_CONTEXT_ON_RESET_EXT;
167 default:
168 UNREACHABLE();
169 return GL_NONE;
170 }
171}
172
173bool GetRobustAccess(const egl::AttributeMap &attribs)
174{
Geoff Lang077f20a2016-11-01 10:08:02 -0400175 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
176 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
177 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500178}
179
180bool GetDebug(const egl::AttributeMap &attribs)
181{
Geoff Lang077f20a2016-11-01 10:08:02 -0400182 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
183 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184}
185
186bool GetNoError(const egl::AttributeMap &attribs)
187{
188 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
189}
190
Geoff Langc287ea62016-09-16 14:46:51 -0400191bool GetWebGLContext(const egl::AttributeMap &attribs)
192{
193 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
194}
195
Geoff Langf41a7152016-09-19 15:11:17 -0400196bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
197{
198 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
199}
200
Martin Radev9d901792016-07-15 15:58:58 +0300201std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
202{
203 std::string labelName;
204 if (label != nullptr)
205 {
206 size_t labelLength = length < 0 ? strlen(label) : length;
207 labelName = std::string(label, labelLength);
208 }
209 return labelName;
210}
211
212void GetObjectLabelBase(const std::string &objectLabel,
213 GLsizei bufSize,
214 GLsizei *length,
215 GLchar *label)
216{
217 size_t writeLength = objectLabel.length();
218 if (label != nullptr && bufSize > 0)
219 {
220 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
221 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
222 label[writeLength] = '\0';
223 }
224
225 if (length != nullptr)
226 {
227 *length = static_cast<GLsizei>(writeLength);
228 }
229}
230
Geoff Langf6db0982015-08-25 13:04:00 -0400231} // anonymous namespace
232
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000233namespace gl
234{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000235
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400236Context::Context(rx::EGLImplFactory *implFactory,
237 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400238 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500239 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500240 const egl::AttributeMap &attribs,
241 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300242
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500243 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500244 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500245 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700246 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500247 mCaps,
248 mTextureCaps,
249 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500250 mLimitations,
251 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700252 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500253 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400254 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500255 mClientType(EGL_OPENGL_ES_API),
256 mHasBeenCurrent(false),
257 mContextLost(false),
258 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700259 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500260 mResetStrategy(GetResetStrategy(attribs)),
261 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500262 mCurrentSurface(nullptr),
263 mSurfacelessFramebuffer(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000264{
Geoff Lang077f20a2016-11-01 10:08:02 -0400265 if (mRobustAccess)
266 {
267 UNIMPLEMENTED();
268 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000269
Corentin Wallezc295e512017-01-27 17:47:50 -0500270 initCaps(GetWebGLContext(attribs), displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700271 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400272
Geoff Langeb66a6e2016-10-31 13:06:12 -0400273 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400274 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100275
Shannon Woods53a94a82014-06-24 15:20:36 -0400276 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400277
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000278 // [OpenGL ES 2.0.24] section 3.7 page 83:
279 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
280 // and cube map texture state vectors respectively associated with them.
281 // In order that access to these initial textures not be lost, they are treated as texture
282 // objects all of whose names are 0.
283
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400284 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500285 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500286
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400287 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500288 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400289
Geoff Langeb66a6e2016-10-31 13:06:12 -0400290 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400291 {
292 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400293 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500294 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400295
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400296 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500297 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400298 }
Geoff Lang3b573612016-10-31 14:08:10 -0400299 if (getClientVersion() >= Version(3, 1))
300 {
301 Texture *zeroTexture2DMultisample =
302 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
303 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
304 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000305
Ian Ewellbda75592016-04-18 17:25:54 -0400306 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
307 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400308 Texture *zeroTextureExternal =
309 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400310 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
311 }
312
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700313 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500314
Jamie Madill57a89722013-07-02 11:57:03 -0400315 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000316 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800317 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000318 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400319
Jamie Madill01a80ee2016-11-07 12:06:18 -0500320 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000321
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000322 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500323 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000324 {
325 bindIndexedUniformBuffer(0, i, 0, -1);
326 }
327
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000328 bindCopyReadBuffer(0);
329 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000330 bindPixelPackBuffer(0);
331 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000332
Geoff Langeb66a6e2016-10-31 13:06:12 -0400333 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400334 {
335 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
336 // In the initial state, a default transform feedback object is bound and treated as
337 // a transform feedback object with a name of zero. That object is bound any time
338 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400339 bindTransformFeedback(0);
340 }
Geoff Langc8058452014-02-03 12:04:11 -0500341
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700342 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500343
344 // Initialize dirty bit masks
345 // TODO(jmadill): additional ES3 state
346 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
347 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
348 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
349 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
350 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
351 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400352 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500353 // No dirty objects.
354
355 // Readpixels uses the pack state and read FBO
356 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
357 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
358 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
359 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
360 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400361 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500362 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
363
364 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
365 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
366 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
367 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
368 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
369 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
370 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
371 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
372 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
373 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
374 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
375 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
376
377 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
378 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700379 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500380 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
381 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400382
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400383 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000384}
385
Jamie Madill70ee0f62017-02-06 16:04:20 -0500386void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000387{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700388 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000389
Corentin Wallez80b24112015-08-25 16:41:57 -0400390 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000391 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400392 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000393 }
394
Corentin Wallez80b24112015-08-25 16:41:57 -0400395 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000396 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400397 if (query.second != nullptr)
398 {
399 query.second->release();
400 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000401 }
402
Corentin Wallez80b24112015-08-25 16:41:57 -0400403 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400404 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400405 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400406 }
407
Corentin Wallez80b24112015-08-25 16:41:57 -0400408 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500409 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500410 if (transformFeedback.second != nullptr)
411 {
412 transformFeedback.second->release();
413 }
Geoff Langc8058452014-02-03 12:04:11 -0500414 }
415
Jamie Madilldedd7b92014-11-05 16:30:36 -0500416 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400417 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500418 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400419 }
420 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421
Corentin Wallezccab69d2017-01-27 16:57:15 -0500422 SafeDelete(mSurfacelessFramebuffer);
423
Jamie Madill70ee0f62017-02-06 16:04:20 -0500424 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400425
Geoff Lang492a7e42014-11-05 13:27:06 -0500426 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427}
428
Jamie Madill70ee0f62017-02-06 16:04:20 -0500429Context::~Context()
430{
431}
432
433void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000434{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435 if (!mHasBeenCurrent)
436 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000437 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500438 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400439 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000440
Corentin Wallezc295e512017-01-27 17:47:50 -0500441 int width = 0;
442 int height = 0;
443 if (surface != nullptr)
444 {
445 width = surface->getWidth();
446 height = surface->getHeight();
447 }
448
449 mGLState.setViewportParams(0, 0, width, height);
450 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000451
452 mHasBeenCurrent = true;
453 }
454
Jamie Madill1b94d432015-08-07 13:23:23 -0400455 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700456 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400457
Jamie Madill70ee0f62017-02-06 16:04:20 -0500458 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500459
460 Framebuffer *newDefault = nullptr;
461 if (surface != nullptr)
462 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500463 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500464 mCurrentSurface = surface;
465 newDefault = surface->getDefaultFramebuffer();
466 }
467 else
468 {
469 if (mSurfacelessFramebuffer == nullptr)
470 {
471 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
472 }
473
474 newDefault = mSurfacelessFramebuffer;
475 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000476
Corentin Wallez37c39792015-08-20 14:19:46 -0400477 // Update default framebuffer, the binding of the previous default
478 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400479 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700480 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400481 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700482 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400483 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700484 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400485 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700486 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400487 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500488 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400489 }
Ian Ewell292f0052016-02-04 10:37:32 -0500490
491 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700492 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493}
494
Jamie Madill70ee0f62017-02-06 16:04:20 -0500495void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400496{
Corentin Wallez37c39792015-08-20 14:19:46 -0400497 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500498 Framebuffer *currentDefault = nullptr;
499 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400500 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500501 currentDefault = mCurrentSurface->getDefaultFramebuffer();
502 }
503 else if (mSurfacelessFramebuffer != nullptr)
504 {
505 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400506 }
507
Corentin Wallezc295e512017-01-27 17:47:50 -0500508 if (mGLState.getReadFramebuffer() == currentDefault)
509 {
510 mGLState.setReadFramebufferBinding(nullptr);
511 }
512 if (mGLState.getDrawFramebuffer() == currentDefault)
513 {
514 mGLState.setDrawFramebufferBinding(nullptr);
515 }
516 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
517
518 if (mCurrentSurface)
519 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500520 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500521 mCurrentSurface = nullptr;
522 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400523}
524
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000525GLuint Context::createBuffer()
526{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500527 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000528}
529
530GLuint Context::createProgram()
531{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500532 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000533}
534
535GLuint Context::createShader(GLenum type)
536{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500537 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000538}
539
540GLuint Context::createTexture()
541{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500542 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000543}
544
545GLuint Context::createRenderbuffer()
546{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500547 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000548}
549
Geoff Lang882033e2014-09-30 11:26:07 -0400550GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400551{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500552 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400553
Cooper Partind8e62a32015-01-29 15:21:25 -0800554 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400555}
556
Sami Väisänene45e53b2016-05-25 10:36:04 +0300557GLuint Context::createPaths(GLsizei range)
558{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500559 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300560 if (resultOrError.isError())
561 {
562 handleError(resultOrError.getError());
563 return 0;
564 }
565 return resultOrError.getResult();
566}
567
Jamie Madill57a89722013-07-02 11:57:03 -0400568GLuint Context::createVertexArray()
569{
Geoff Lang36167ab2015-12-07 10:27:14 -0500570 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
571 mVertexArrayMap[vertexArray] = nullptr;
572 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400573}
574
Jamie Madilldc356042013-07-19 16:36:57 -0400575GLuint Context::createSampler()
576{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500577 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400578}
579
Geoff Langc8058452014-02-03 12:04:11 -0500580GLuint Context::createTransformFeedback()
581{
Geoff Lang36167ab2015-12-07 10:27:14 -0500582 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
583 mTransformFeedbackMap[transformFeedback] = nullptr;
584 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500585}
586
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587// Returns an unused framebuffer name
588GLuint Context::createFramebuffer()
589{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500590 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000591}
592
Jamie Madill33dc8432013-07-26 11:55:05 -0400593GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000594{
Jamie Madill33dc8432013-07-26 11:55:05 -0400595 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000596
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400597 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000598
599 return handle;
600}
601
602// Returns an unused query name
603GLuint Context::createQuery()
604{
605 GLuint handle = mQueryHandleAllocator.allocate();
606
607 mQueryMap[handle] = NULL;
608
609 return handle;
610}
611
612void Context::deleteBuffer(GLuint buffer)
613{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500614 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000615 {
616 detachBuffer(buffer);
617 }
Jamie Madill893ab082014-05-16 16:56:10 -0400618
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500619 mState.mBuffers->deleteBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620}
621
622void Context::deleteShader(GLuint shader)
623{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500624 mState.mShaderPrograms->deleteShader(shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625}
626
627void Context::deleteProgram(GLuint program)
628{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500629 mState.mShaderPrograms->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630}
631
632void Context::deleteTexture(GLuint texture)
633{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500634 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000635 {
636 detachTexture(texture);
637 }
638
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500639 mState.mTextures->deleteTexture(texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000640}
641
642void Context::deleteRenderbuffer(GLuint renderbuffer)
643{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500644 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000645 {
646 detachRenderbuffer(renderbuffer);
647 }
Jamie Madill893ab082014-05-16 16:56:10 -0400648
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500649 mState.mRenderbuffers->deleteRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000650}
651
Jamie Madillcd055f82013-07-26 11:55:15 -0400652void Context::deleteFenceSync(GLsync fenceSync)
653{
654 // The spec specifies the underlying Fence object is not deleted until all current
655 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
656 // and since our API is currently designed for being called from a single thread, we can delete
657 // the fence immediately.
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500658 mState.mFenceSyncs->deleteFenceSync(
659 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400660}
661
Sami Väisänene45e53b2016-05-25 10:36:04 +0300662void Context::deletePaths(GLuint first, GLsizei range)
663{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500664 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300665}
666
667bool Context::hasPathData(GLuint path) const
668{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500669 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300670 if (pathObj == nullptr)
671 return false;
672
673 return pathObj->hasPathData();
674}
675
676bool Context::hasPath(GLuint path) const
677{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500678 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300679}
680
681void Context::setPathCommands(GLuint path,
682 GLsizei numCommands,
683 const GLubyte *commands,
684 GLsizei numCoords,
685 GLenum coordType,
686 const void *coords)
687{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500688 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300689
690 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
691}
692
693void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
694{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500695 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300696
697 switch (pname)
698 {
699 case GL_PATH_STROKE_WIDTH_CHROMIUM:
700 pathObj->setStrokeWidth(value);
701 break;
702 case GL_PATH_END_CAPS_CHROMIUM:
703 pathObj->setEndCaps(static_cast<GLenum>(value));
704 break;
705 case GL_PATH_JOIN_STYLE_CHROMIUM:
706 pathObj->setJoinStyle(static_cast<GLenum>(value));
707 break;
708 case GL_PATH_MITER_LIMIT_CHROMIUM:
709 pathObj->setMiterLimit(value);
710 break;
711 case GL_PATH_STROKE_BOUND_CHROMIUM:
712 pathObj->setStrokeBound(value);
713 break;
714 default:
715 UNREACHABLE();
716 break;
717 }
718}
719
720void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
721{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500722 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300723
724 switch (pname)
725 {
726 case GL_PATH_STROKE_WIDTH_CHROMIUM:
727 *value = pathObj->getStrokeWidth();
728 break;
729 case GL_PATH_END_CAPS_CHROMIUM:
730 *value = static_cast<GLfloat>(pathObj->getEndCaps());
731 break;
732 case GL_PATH_JOIN_STYLE_CHROMIUM:
733 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
734 break;
735 case GL_PATH_MITER_LIMIT_CHROMIUM:
736 *value = pathObj->getMiterLimit();
737 break;
738 case GL_PATH_STROKE_BOUND_CHROMIUM:
739 *value = pathObj->getStrokeBound();
740 break;
741 default:
742 UNREACHABLE();
743 break;
744 }
745}
746
747void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
748{
749 mGLState.setPathStencilFunc(func, ref, mask);
750}
751
Jamie Madill57a89722013-07-02 11:57:03 -0400752void Context::deleteVertexArray(GLuint vertexArray)
753{
Geoff Lang36167ab2015-12-07 10:27:14 -0500754 auto iter = mVertexArrayMap.find(vertexArray);
755 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000756 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500757 VertexArray *vertexArrayObject = iter->second;
758 if (vertexArrayObject != nullptr)
759 {
760 detachVertexArray(vertexArray);
761 delete vertexArrayObject;
762 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000763
Geoff Lang36167ab2015-12-07 10:27:14 -0500764 mVertexArrayMap.erase(iter);
765 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400766 }
767}
768
Jamie Madilldc356042013-07-19 16:36:57 -0400769void Context::deleteSampler(GLuint sampler)
770{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500771 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400772 {
773 detachSampler(sampler);
774 }
775
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500776 mState.mSamplers->deleteSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400777}
778
Geoff Langc8058452014-02-03 12:04:11 -0500779void Context::deleteTransformFeedback(GLuint transformFeedback)
780{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500781 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500782 if (iter != mTransformFeedbackMap.end())
783 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500784 TransformFeedback *transformFeedbackObject = iter->second;
785 if (transformFeedbackObject != nullptr)
786 {
787 detachTransformFeedback(transformFeedback);
788 transformFeedbackObject->release();
789 }
790
Geoff Lang50b3fe82015-12-08 14:49:12 +0000791 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500792 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500793 }
794}
795
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796void Context::deleteFramebuffer(GLuint framebuffer)
797{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500798 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000799 {
800 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500802
803 mState.mFramebuffers->deleteFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000804}
805
Jamie Madill33dc8432013-07-26 11:55:05 -0400806void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000807{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500808 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000809
Jamie Madill33dc8432013-07-26 11:55:05 -0400810 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000811 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400812 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400814 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815 }
816}
817
818void Context::deleteQuery(GLuint query)
819{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500820 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821 if (queryObject != mQueryMap.end())
822 {
823 mQueryHandleAllocator.release(queryObject->first);
824 if (queryObject->second)
825 {
826 queryObject->second->release();
827 }
828 mQueryMap.erase(queryObject);
829 }
830}
831
Geoff Lang70d0f492015-12-10 17:45:46 -0500832Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000833{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500834 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835}
836
Jamie Madill570f7c82014-07-03 10:38:54 -0400837Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000838{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500839 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840}
841
Geoff Lang70d0f492015-12-10 17:45:46 -0500842Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500844 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000845}
846
Jamie Madillcd055f82013-07-26 11:55:15 -0400847FenceSync *Context::getFenceSync(GLsync handle) const
848{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500849 return mState.mFenceSyncs->getFenceSync(
850 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400851}
852
Jamie Madill57a89722013-07-02 11:57:03 -0400853VertexArray *Context::getVertexArray(GLuint handle) const
854{
855 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500856 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400857}
858
Jamie Madilldc356042013-07-19 16:36:57 -0400859Sampler *Context::getSampler(GLuint handle) const
860{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500861 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400862}
863
Geoff Langc8058452014-02-03 12:04:11 -0500864TransformFeedback *Context::getTransformFeedback(GLuint handle) const
865{
Geoff Lang36167ab2015-12-07 10:27:14 -0500866 auto iter = mTransformFeedbackMap.find(handle);
867 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500868}
869
Geoff Lang70d0f492015-12-10 17:45:46 -0500870LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
871{
872 switch (identifier)
873 {
874 case GL_BUFFER:
875 return getBuffer(name);
876 case GL_SHADER:
877 return getShader(name);
878 case GL_PROGRAM:
879 return getProgram(name);
880 case GL_VERTEX_ARRAY:
881 return getVertexArray(name);
882 case GL_QUERY:
883 return getQuery(name);
884 case GL_TRANSFORM_FEEDBACK:
885 return getTransformFeedback(name);
886 case GL_SAMPLER:
887 return getSampler(name);
888 case GL_TEXTURE:
889 return getTexture(name);
890 case GL_RENDERBUFFER:
891 return getRenderbuffer(name);
892 case GL_FRAMEBUFFER:
893 return getFramebuffer(name);
894 default:
895 UNREACHABLE();
896 return nullptr;
897 }
898}
899
900LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
901{
902 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
903}
904
Martin Radev9d901792016-07-15 15:58:58 +0300905void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
906{
907 LabeledObject *object = getLabeledObject(identifier, name);
908 ASSERT(object != nullptr);
909
910 std::string labelName = GetObjectLabelFromPointer(length, label);
911 object->setLabel(labelName);
912}
913
914void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
915{
916 LabeledObject *object = getLabeledObjectFromPtr(ptr);
917 ASSERT(object != nullptr);
918
919 std::string labelName = GetObjectLabelFromPointer(length, label);
920 object->setLabel(labelName);
921}
922
923void Context::getObjectLabel(GLenum identifier,
924 GLuint name,
925 GLsizei bufSize,
926 GLsizei *length,
927 GLchar *label) const
928{
929 LabeledObject *object = getLabeledObject(identifier, name);
930 ASSERT(object != nullptr);
931
932 const std::string &objectLabel = object->getLabel();
933 GetObjectLabelBase(objectLabel, bufSize, length, label);
934}
935
936void Context::getObjectPtrLabel(const void *ptr,
937 GLsizei bufSize,
938 GLsizei *length,
939 GLchar *label) const
940{
941 LabeledObject *object = getLabeledObjectFromPtr(ptr);
942 ASSERT(object != nullptr);
943
944 const std::string &objectLabel = object->getLabel();
945 GetObjectLabelBase(objectLabel, bufSize, length, label);
946}
947
Jamie Madilldc356042013-07-19 16:36:57 -0400948bool Context::isSampler(GLuint samplerName) const
949{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500950 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400951}
952
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500953void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500955 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700956 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000957}
958
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800959void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
960{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500961 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800962 mGLState.setDrawIndirectBufferBinding(buffer);
963}
964
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500965void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000966{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500967 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700968 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000969}
970
Jamie Madilldedd7b92014-11-05 16:30:36 -0500971void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000972{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500973 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974
Jamie Madilldedd7b92014-11-05 16:30:36 -0500975 if (handle == 0)
976 {
977 texture = mZeroTextures[target].get();
978 }
979 else
980 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500981 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500982 }
983
984 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700985 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000986}
987
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500988void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500990 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
991 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700992 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993}
994
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500995void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500997 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
998 mImplementation.get(), mCaps, 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
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001171Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001173 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174}
1175
Jamie Madill33dc8432013-07-26 11:55:05 -04001176FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001178 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179
Jamie Madill33dc8432013-07-26 11:55:05 -04001180 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181 {
1182 return NULL;
1183 }
1184 else
1185 {
1186 return fence->second;
1187 }
1188}
1189
1190Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1191{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001192 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193
1194 if (query == mQueryMap.end())
1195 {
1196 return NULL;
1197 }
1198 else
1199 {
1200 if (!query->second && create)
1201 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001202 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001203 query->second->addRef();
1204 }
1205 return query->second;
1206 }
1207}
1208
Geoff Lang70d0f492015-12-10 17:45:46 -05001209Query *Context::getQuery(GLuint handle) const
1210{
1211 auto iter = mQueryMap.find(handle);
1212 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1213}
1214
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001215Texture *Context::getTargetTexture(GLenum target) const
1216{
Ian Ewellbda75592016-04-18 17:25:54 -04001217 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001218 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001219}
1220
Geoff Lang76b10c92014-09-05 16:28:14 -04001221Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001222{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001223 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001224}
1225
Geoff Lang492a7e42014-11-05 13:27:06 -05001226Compiler *Context::getCompiler() const
1227{
1228 return mCompiler;
1229}
1230
Jamie Madill893ab082014-05-16 16:56:10 -04001231void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232{
1233 switch (pname)
1234 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001235 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001236 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001238 mGLState.getBooleanv(pname, params);
1239 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241}
1242
Jamie Madill893ab082014-05-16 16:56:10 -04001243void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244{
Shannon Woods53a94a82014-06-24 15:20:36 -04001245 // Queries about context capabilities and maximums are answered by Context.
1246 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001247 switch (pname)
1248 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001249 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001250 params[0] = mCaps.minAliasedLineWidth;
1251 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001252 break;
1253 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001254 params[0] = mCaps.minAliasedPointSize;
1255 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001256 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001257 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001258 ASSERT(mExtensions.textureFilterAnisotropic);
1259 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001260 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001261 case GL_MAX_TEXTURE_LOD_BIAS:
1262 *params = mCaps.maxLODBias;
1263 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001264
1265 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1266 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1267 {
1268 ASSERT(mExtensions.pathRendering);
1269 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1270 memcpy(params, m, 16 * sizeof(GLfloat));
1271 }
1272 break;
1273
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001275 mGLState.getFloatv(pname, params);
1276 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278}
1279
Jamie Madill893ab082014-05-16 16:56:10 -04001280void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281{
Shannon Woods53a94a82014-06-24 15:20:36 -04001282 // Queries about context capabilities and maximums are answered by Context.
1283 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001284
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001285 switch (pname)
1286 {
Geoff Lang301d1612014-07-09 10:34:37 -04001287 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1288 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1289 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001290 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1291 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1292 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001293 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1294 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1295 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001296 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001297 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1298 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1299 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001300 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001301 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001302 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1303 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1304 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1305 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001306 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1307 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001308 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1309 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001310 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001311 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1312 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1313 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1314 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001315 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001316 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001317 break;
1318 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001319 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001320 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001321 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1322 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001323 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1324 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1325 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001326 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1327 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1328 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001329 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 case GL_MAX_VIEWPORT_DIMS:
1331 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001332 params[0] = mCaps.maxViewportWidth;
1333 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001334 }
1335 break;
1336 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001337 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001338 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001339 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1340 *params = mResetStrategy;
1341 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001342 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001343 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001344 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001345 case GL_SHADER_BINARY_FORMATS:
1346 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1347 break;
1348 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001349 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001350 break;
1351 case GL_PROGRAM_BINARY_FORMATS:
1352 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001353 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001354 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001355 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001356 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001357
1358 // GL_KHR_debug
1359 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1360 *params = mExtensions.maxDebugMessageLength;
1361 break;
1362 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1363 *params = mExtensions.maxDebugLoggedMessages;
1364 break;
1365 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1366 *params = mExtensions.maxDebugGroupStackDepth;
1367 break;
1368 case GL_MAX_LABEL_LENGTH:
1369 *params = mExtensions.maxLabelLength;
1370 break;
1371
Ian Ewell53f59f42016-01-28 17:36:55 -05001372 // GL_EXT_disjoint_timer_query
1373 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001374 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001375 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001376 case GL_MAX_FRAMEBUFFER_WIDTH:
1377 *params = mCaps.maxFramebufferWidth;
1378 break;
1379 case GL_MAX_FRAMEBUFFER_HEIGHT:
1380 *params = mCaps.maxFramebufferHeight;
1381 break;
1382 case GL_MAX_FRAMEBUFFER_SAMPLES:
1383 *params = mCaps.maxFramebufferSamples;
1384 break;
1385 case GL_MAX_SAMPLE_MASK_WORDS:
1386 *params = mCaps.maxSampleMaskWords;
1387 break;
1388 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1389 *params = mCaps.maxColorTextureSamples;
1390 break;
1391 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1392 *params = mCaps.maxDepthTextureSamples;
1393 break;
1394 case GL_MAX_INTEGER_SAMPLES:
1395 *params = mCaps.maxIntegerSamples;
1396 break;
1397 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1398 *params = mCaps.maxVertexAttribRelativeOffset;
1399 break;
1400 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1401 *params = mCaps.maxVertexAttribBindings;
1402 break;
1403 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1404 *params = mCaps.maxVertexAttribStride;
1405 break;
1406 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1407 *params = mCaps.maxVertexAtomicCounterBuffers;
1408 break;
1409 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1410 *params = mCaps.maxVertexAtomicCounters;
1411 break;
1412 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1413 *params = mCaps.maxVertexImageUniforms;
1414 break;
1415 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1416 *params = mCaps.maxVertexShaderStorageBlocks;
1417 break;
1418 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1419 *params = mCaps.maxFragmentAtomicCounterBuffers;
1420 break;
1421 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1422 *params = mCaps.maxFragmentAtomicCounters;
1423 break;
1424 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1425 *params = mCaps.maxFragmentImageUniforms;
1426 break;
1427 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1428 *params = mCaps.maxFragmentShaderStorageBlocks;
1429 break;
1430 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1431 *params = mCaps.minProgramTextureGatherOffset;
1432 break;
1433 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1434 *params = mCaps.maxProgramTextureGatherOffset;
1435 break;
1436 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1437 *params = mCaps.maxComputeWorkGroupInvocations;
1438 break;
1439 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1440 *params = mCaps.maxComputeUniformBlocks;
1441 break;
1442 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1443 *params = mCaps.maxComputeTextureImageUnits;
1444 break;
1445 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1446 *params = mCaps.maxComputeSharedMemorySize;
1447 break;
1448 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1449 *params = mCaps.maxComputeUniformComponents;
1450 break;
1451 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1452 *params = mCaps.maxComputeAtomicCounterBuffers;
1453 break;
1454 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1455 *params = mCaps.maxComputeAtomicCounters;
1456 break;
1457 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1458 *params = mCaps.maxComputeImageUniforms;
1459 break;
1460 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1461 *params = mCaps.maxCombinedComputeUniformComponents;
1462 break;
1463 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1464 *params = mCaps.maxComputeShaderStorageBlocks;
1465 break;
1466 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1467 *params = mCaps.maxCombinedShaderOutputResources;
1468 break;
1469 case GL_MAX_UNIFORM_LOCATIONS:
1470 *params = mCaps.maxUniformLocations;
1471 break;
1472 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1473 *params = mCaps.maxAtomicCounterBufferBindings;
1474 break;
1475 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1476 *params = mCaps.maxAtomicCounterBufferSize;
1477 break;
1478 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1479 *params = mCaps.maxCombinedAtomicCounterBuffers;
1480 break;
1481 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1482 *params = mCaps.maxCombinedAtomicCounters;
1483 break;
1484 case GL_MAX_IMAGE_UNITS:
1485 *params = mCaps.maxImageUnits;
1486 break;
1487 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1488 *params = mCaps.maxCombinedImageUniforms;
1489 break;
1490 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1491 *params = mCaps.maxShaderStorageBufferBindings;
1492 break;
1493 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1494 *params = mCaps.maxCombinedShaderStorageBlocks;
1495 break;
1496 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1497 *params = mCaps.shaderStorageBufferOffsetAlignment;
1498 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001499 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001500 mGLState.getIntegerv(mState, pname, params);
1501 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001502 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001503}
1504
Jamie Madill893ab082014-05-16 16:56:10 -04001505void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001506{
Shannon Woods53a94a82014-06-24 15:20:36 -04001507 // Queries about context capabilities and maximums are answered by Context.
1508 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001509 switch (pname)
1510 {
1511 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001512 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001513 break;
1514 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001515 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001516 break;
1517 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001518 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001519 break;
1520 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001521 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001522 break;
1523 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001524 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001525 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001526
1527 // GL_EXT_disjoint_timer_query
1528 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001529 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001530 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001531
1532 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1533 *params = mCaps.maxShaderStorageBlockSize;
1534 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001535 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001536 UNREACHABLE();
1537 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001538 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001539}
1540
Geoff Lang70d0f492015-12-10 17:45:46 -05001541void Context::getPointerv(GLenum pname, void **params) const
1542{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001543 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001544}
1545
Martin Radev66fb8202016-07-28 11:45:20 +03001546void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001547{
Shannon Woods53a94a82014-06-24 15:20:36 -04001548 // Queries about context capabilities and maximums are answered by Context.
1549 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001550
1551 GLenum nativeType;
1552 unsigned int numParams;
1553 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1554 ASSERT(queryStatus);
1555
1556 if (nativeType == GL_INT)
1557 {
1558 switch (target)
1559 {
1560 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1561 ASSERT(index < 3u);
1562 *data = mCaps.maxComputeWorkGroupCount[index];
1563 break;
1564 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1565 ASSERT(index < 3u);
1566 *data = mCaps.maxComputeWorkGroupSize[index];
1567 break;
1568 default:
1569 mGLState.getIntegeri_v(target, index, data);
1570 }
1571 }
1572 else
1573 {
1574 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1575 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001576}
1577
Martin Radev66fb8202016-07-28 11:45:20 +03001578void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001579{
Shannon Woods53a94a82014-06-24 15:20:36 -04001580 // Queries about context capabilities and maximums are answered by Context.
1581 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001582
1583 GLenum nativeType;
1584 unsigned int numParams;
1585 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1586 ASSERT(queryStatus);
1587
1588 if (nativeType == GL_INT_64_ANGLEX)
1589 {
1590 mGLState.getInteger64i_v(target, index, data);
1591 }
1592 else
1593 {
1594 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1595 }
1596}
1597
1598void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1599{
1600 // Queries about context capabilities and maximums are answered by Context.
1601 // Queries about current GL state values are answered by State.
1602
1603 GLenum nativeType;
1604 unsigned int numParams;
1605 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1606 ASSERT(queryStatus);
1607
1608 if (nativeType == GL_BOOL)
1609 {
1610 mGLState.getBooleani_v(target, index, data);
1611 }
1612 else
1613 {
1614 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1615 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001616}
1617
Jamie Madill675fe712016-12-19 13:07:54 -05001618void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001619{
Jamie Madill1b94d432015-08-07 13:23:23 -04001620 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001621 auto error = mImplementation->drawArrays(mode, first, count);
1622 handleError(error);
1623 if (!error.isError())
1624 {
1625 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1626 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001627}
1628
Jamie Madill675fe712016-12-19 13:07:54 -05001629void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001630{
1631 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001632 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1633 handleError(error);
1634 if (!error.isError())
1635 {
1636 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1637 }
Geoff Langf6db0982015-08-25 13:04:00 -04001638}
1639
Jamie Madill675fe712016-12-19 13:07:54 -05001640void Context::drawElements(GLenum mode,
1641 GLsizei count,
1642 GLenum type,
1643 const GLvoid *indices,
1644 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001645{
Jamie Madill1b94d432015-08-07 13:23:23 -04001646 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001647 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001648}
1649
Jamie Madill675fe712016-12-19 13:07:54 -05001650void Context::drawElementsInstanced(GLenum mode,
1651 GLsizei count,
1652 GLenum type,
1653 const GLvoid *indices,
1654 GLsizei instances,
1655 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001656{
1657 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001658 handleError(
1659 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001660}
1661
Jamie Madill675fe712016-12-19 13:07:54 -05001662void Context::drawRangeElements(GLenum mode,
1663 GLuint start,
1664 GLuint end,
1665 GLsizei count,
1666 GLenum type,
1667 const GLvoid *indices,
1668 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001669{
1670 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001671 handleError(
1672 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001673}
1674
Jiajia Qind9671222016-11-29 16:30:31 +08001675void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1676{
1677 syncRendererState();
1678 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1679}
1680
1681void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1682{
1683 syncRendererState();
1684 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1685}
1686
Jamie Madill675fe712016-12-19 13:07:54 -05001687void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001688{
Jamie Madill675fe712016-12-19 13:07:54 -05001689 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001690}
1691
Jamie Madill675fe712016-12-19 13:07:54 -05001692void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001693{
Jamie Madill675fe712016-12-19 13:07:54 -05001694 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001695}
1696
Austin Kinross6ee1e782015-05-29 17:05:37 -07001697void Context::insertEventMarker(GLsizei length, const char *marker)
1698{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001699 ASSERT(mImplementation);
1700 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001701}
1702
1703void Context::pushGroupMarker(GLsizei length, const char *marker)
1704{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001705 ASSERT(mImplementation);
1706 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001707}
1708
1709void Context::popGroupMarker()
1710{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001711 ASSERT(mImplementation);
1712 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001713}
1714
Geoff Langd8605522016-04-13 10:19:12 -04001715void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1716{
1717 Program *programObject = getProgram(program);
1718 ASSERT(programObject);
1719
1720 programObject->bindUniformLocation(location, name);
1721}
1722
Sami Väisänena797e062016-05-12 15:23:40 +03001723void Context::setCoverageModulation(GLenum components)
1724{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001725 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001726}
1727
Sami Väisänene45e53b2016-05-25 10:36:04 +03001728void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1729{
1730 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1731}
1732
1733void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1734{
1735 GLfloat I[16];
1736 angle::Matrix<GLfloat>::setToIdentity(I);
1737
1738 mGLState.loadPathRenderingMatrix(matrixMode, I);
1739}
1740
1741void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1742{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001743 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001744 if (!pathObj)
1745 return;
1746
1747 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1748 syncRendererState();
1749
1750 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1751}
1752
1753void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1754{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001755 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001756 if (!pathObj)
1757 return;
1758
1759 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1760 syncRendererState();
1761
1762 mImplementation->stencilStrokePath(pathObj, reference, mask);
1763}
1764
1765void Context::coverFillPath(GLuint path, GLenum coverMode)
1766{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001767 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001768 if (!pathObj)
1769 return;
1770
1771 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1772 syncRendererState();
1773
1774 mImplementation->coverFillPath(pathObj, coverMode);
1775}
1776
1777void Context::coverStrokePath(GLuint path, GLenum coverMode)
1778{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001779 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001780 if (!pathObj)
1781 return;
1782
1783 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1784 syncRendererState();
1785
1786 mImplementation->coverStrokePath(pathObj, coverMode);
1787}
1788
1789void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1790{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001791 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001792 if (!pathObj)
1793 return;
1794
1795 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1796 syncRendererState();
1797
1798 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1799}
1800
1801void Context::stencilThenCoverStrokePath(GLuint path,
1802 GLint reference,
1803 GLuint mask,
1804 GLenum coverMode)
1805{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001806 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001807 if (!pathObj)
1808 return;
1809
1810 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1811 syncRendererState();
1812
1813 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1814}
1815
Sami Väisänend59ca052016-06-21 16:10:00 +03001816void Context::coverFillPathInstanced(GLsizei numPaths,
1817 GLenum pathNameType,
1818 const void *paths,
1819 GLuint pathBase,
1820 GLenum coverMode,
1821 GLenum transformType,
1822 const GLfloat *transformValues)
1823{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001824 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001825
1826 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1827 syncRendererState();
1828
1829 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1830}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001831
Sami Väisänend59ca052016-06-21 16:10:00 +03001832void Context::coverStrokePathInstanced(GLsizei numPaths,
1833 GLenum pathNameType,
1834 const void *paths,
1835 GLuint pathBase,
1836 GLenum coverMode,
1837 GLenum transformType,
1838 const GLfloat *transformValues)
1839{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001840 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001841
1842 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1843 syncRendererState();
1844
1845 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1846 transformValues);
1847}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001848
Sami Väisänend59ca052016-06-21 16:10:00 +03001849void Context::stencilFillPathInstanced(GLsizei numPaths,
1850 GLenum pathNameType,
1851 const void *paths,
1852 GLuint pathBase,
1853 GLenum fillMode,
1854 GLuint mask,
1855 GLenum transformType,
1856 const GLfloat *transformValues)
1857{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001858 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001859
1860 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1861 syncRendererState();
1862
1863 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1864 transformValues);
1865}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001866
Sami Väisänend59ca052016-06-21 16:10:00 +03001867void Context::stencilStrokePathInstanced(GLsizei numPaths,
1868 GLenum pathNameType,
1869 const void *paths,
1870 GLuint pathBase,
1871 GLint reference,
1872 GLuint mask,
1873 GLenum transformType,
1874 const GLfloat *transformValues)
1875{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001876 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001877
1878 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1879 syncRendererState();
1880
1881 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1882 transformValues);
1883}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001884
Sami Väisänend59ca052016-06-21 16:10:00 +03001885void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1886 GLenum pathNameType,
1887 const void *paths,
1888 GLuint pathBase,
1889 GLenum fillMode,
1890 GLuint mask,
1891 GLenum coverMode,
1892 GLenum transformType,
1893 const GLfloat *transformValues)
1894{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001895 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001896
1897 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1898 syncRendererState();
1899
1900 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1901 transformType, transformValues);
1902}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001903
Sami Väisänend59ca052016-06-21 16:10:00 +03001904void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1905 GLenum pathNameType,
1906 const void *paths,
1907 GLuint pathBase,
1908 GLint reference,
1909 GLuint mask,
1910 GLenum coverMode,
1911 GLenum transformType,
1912 const GLfloat *transformValues)
1913{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001914 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001915
1916 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1917 syncRendererState();
1918
1919 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1920 transformType, transformValues);
1921}
1922
Sami Väisänen46eaa942016-06-29 10:26:37 +03001923void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1924{
1925 auto *programObject = getProgram(program);
1926
1927 programObject->bindFragmentInputLocation(location, name);
1928}
1929
1930void Context::programPathFragmentInputGen(GLuint program,
1931 GLint location,
1932 GLenum genMode,
1933 GLint components,
1934 const GLfloat *coeffs)
1935{
1936 auto *programObject = getProgram(program);
1937
1938 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1939}
1940
Jamie Madill437fa652016-05-03 15:13:24 -04001941void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001942{
Geoff Langda5777c2014-07-11 09:52:58 -04001943 if (error.isError())
1944 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001945 GLenum code = error.getCode();
1946 mErrors.insert(code);
1947 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1948 {
1949 markContextLost();
1950 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001951
1952 if (!error.getMessage().empty())
1953 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001954 auto *debug = &mGLState.getDebug();
1955 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1956 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001957 }
Geoff Langda5777c2014-07-11 09:52:58 -04001958 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001959}
1960
1961// Get one of the recorded errors and clear its flag, if any.
1962// [OpenGL ES 2.0.24] section 2.5 page 13.
1963GLenum Context::getError()
1964{
Geoff Langda5777c2014-07-11 09:52:58 -04001965 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001966 {
Geoff Langda5777c2014-07-11 09:52:58 -04001967 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001968 }
Geoff Langda5777c2014-07-11 09:52:58 -04001969 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001970 {
Geoff Langda5777c2014-07-11 09:52:58 -04001971 GLenum error = *mErrors.begin();
1972 mErrors.erase(mErrors.begin());
1973 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001974 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001975}
1976
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001977// NOTE: this function should not assume that this context is current!
1978void Context::markContextLost()
1979{
1980 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001981 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001982 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001983 mContextLostForced = true;
1984 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001985 mContextLost = true;
1986}
1987
1988bool Context::isContextLost()
1989{
1990 return mContextLost;
1991}
1992
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001993GLenum Context::getResetStatus()
1994{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001995 // Even if the application doesn't want to know about resets, we want to know
1996 // as it will allow us to skip all the calls.
1997 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001998 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001999 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002000 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002001 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002002 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002003
2004 // EXT_robustness, section 2.6: If the reset notification behavior is
2005 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2006 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2007 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002008 }
2009
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002010 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2011 // status should be returned at least once, and GL_NO_ERROR should be returned
2012 // once the device has finished resetting.
2013 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002014 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002015 ASSERT(mResetStatus == GL_NO_ERROR);
2016 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002017
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002018 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002019 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002020 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002021 }
2022 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002023 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002024 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002025 // If markContextLost was used to mark the context lost then
2026 // assume that is not recoverable, and continue to report the
2027 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002028 mResetStatus = mImplementation->getResetStatus();
2029 }
Jamie Madill893ab082014-05-16 16:56:10 -04002030
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002031 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002032}
2033
2034bool Context::isResetNotificationEnabled()
2035{
2036 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2037}
2038
Corentin Walleze3b10e82015-05-20 11:06:25 -04002039const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002040{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002041 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002042}
2043
2044EGLenum Context::getClientType() const
2045{
2046 return mClientType;
2047}
2048
2049EGLenum Context::getRenderBuffer() const
2050{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002051 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2052 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002053 {
2054 return EGL_NONE;
2055 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002056
2057 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2058 ASSERT(backAttachment != nullptr);
2059 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002060}
2061
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002062VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002063{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002064 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002065 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2066 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002067 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002068 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2069
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002070 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002071 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002072
2073 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002074}
2075
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002076TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002077{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002078 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002079 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2080 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002081 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002082 transformFeedback =
2083 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002084 transformFeedback->addRef();
2085 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002086 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002087
2088 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002089}
2090
2091bool Context::isVertexArrayGenerated(GLuint vertexArray)
2092{
Geoff Langf41a7152016-09-19 15:11:17 -04002093 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002094 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2095}
2096
2097bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2098{
Geoff Langf41a7152016-09-19 15:11:17 -04002099 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002100 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2101}
2102
Shannon Woods53a94a82014-06-24 15:20:36 -04002103void Context::detachTexture(GLuint texture)
2104{
2105 // Simple pass-through to State's detachTexture method, as textures do not require
2106 // allocation map management either here or in the resource manager at detach time.
2107 // Zero textures are held by the Context, and we don't attempt to request them from
2108 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002109 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002110}
2111
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002112void Context::detachBuffer(GLuint buffer)
2113{
Yuly Novikov5807a532015-12-03 13:01:22 -05002114 // Simple pass-through to State's detachBuffer method, since
2115 // only buffer attachments to container objects that are bound to the current context
2116 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002117
Yuly Novikov5807a532015-12-03 13:01:22 -05002118 // [OpenGL ES 3.2] section 5.1.2 page 45:
2119 // Attachments to unbound container objects, such as
2120 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2121 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002122 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002123}
2124
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002125void Context::detachFramebuffer(GLuint framebuffer)
2126{
Shannon Woods53a94a82014-06-24 15:20:36 -04002127 // Framebuffer detachment is handled by Context, because 0 is a valid
2128 // Framebuffer object, and a pointer to it must be passed from Context
2129 // to State at binding time.
2130
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002131 // [OpenGL ES 2.0.24] section 4.4 page 107:
2132 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2133 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2134
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002135 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002136 {
2137 bindReadFramebuffer(0);
2138 }
2139
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002140 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002141 {
2142 bindDrawFramebuffer(0);
2143 }
2144}
2145
2146void Context::detachRenderbuffer(GLuint renderbuffer)
2147{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002148 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002149}
2150
Jamie Madill57a89722013-07-02 11:57:03 -04002151void Context::detachVertexArray(GLuint vertexArray)
2152{
Jamie Madill77a72f62015-04-14 11:18:32 -04002153 // Vertex array detachment is handled by Context, because 0 is a valid
2154 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002155 // binding time.
2156
Jamie Madill57a89722013-07-02 11:57:03 -04002157 // [OpenGL ES 3.0.2] section 2.10 page 43:
2158 // If a vertex array object that is currently bound is deleted, the binding
2159 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002160 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002161 {
2162 bindVertexArray(0);
2163 }
2164}
2165
Geoff Langc8058452014-02-03 12:04:11 -05002166void Context::detachTransformFeedback(GLuint transformFeedback)
2167{
Corentin Walleza2257da2016-04-19 16:43:12 -04002168 // Transform feedback detachment is handled by Context, because 0 is a valid
2169 // transform feedback, and a pointer to it must be passed from Context to State at
2170 // binding time.
2171
2172 // The OpenGL specification doesn't mention what should happen when the currently bound
2173 // transform feedback object is deleted. Since it is a container object, we treat it like
2174 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002175 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002176 {
2177 bindTransformFeedback(0);
2178 }
Geoff Langc8058452014-02-03 12:04:11 -05002179}
2180
Jamie Madilldc356042013-07-19 16:36:57 -04002181void Context::detachSampler(GLuint sampler)
2182{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002183 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002184}
2185
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002186void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2187{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002188 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002189}
2190
Jamie Madille29d1672013-07-19 16:36:57 -04002191void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2192{
Geoff Langc1984ed2016-10-07 12:41:00 -04002193 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002194 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002195 SetSamplerParameteri(samplerObject, pname, param);
2196}
Jamie Madille29d1672013-07-19 16:36:57 -04002197
Geoff Langc1984ed2016-10-07 12:41:00 -04002198void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2199{
2200 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002201 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002202 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002203}
2204
2205void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2206{
Geoff Langc1984ed2016-10-07 12:41:00 -04002207 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002208 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002209 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002210}
2211
Geoff Langc1984ed2016-10-07 12:41:00 -04002212void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002213{
Geoff Langc1984ed2016-10-07 12:41:00 -04002214 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002215 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002216 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002217}
2218
Geoff Langc1984ed2016-10-07 12:41:00 -04002219void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002220{
Geoff Langc1984ed2016-10-07 12:41:00 -04002221 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002222 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002223 QuerySamplerParameteriv(samplerObject, pname, params);
2224}
Jamie Madill9675b802013-07-19 16:36:59 -04002225
Geoff Langc1984ed2016-10-07 12:41:00 -04002226void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2227{
2228 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002229 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002230 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002231}
2232
Olli Etuahof0fee072016-03-30 15:11:58 +03002233void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2234{
2235 gl::Program *programObject = getProgram(program);
2236 ASSERT(programObject != nullptr);
2237
2238 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2239 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2240}
2241
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002242void Context::initRendererString()
2243{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002244 std::ostringstream rendererString;
2245 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002246 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002247 rendererString << ")";
2248
Geoff Langcec35902014-04-16 10:52:36 -04002249 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002250}
2251
Geoff Langc339c4e2016-11-29 10:37:36 -05002252void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002253{
Geoff Langc339c4e2016-11-29 10:37:36 -05002254 const Version &clientVersion = getClientVersion();
2255
2256 std::ostringstream versionString;
2257 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2258 << ANGLE_VERSION_STRING << ")";
2259 mVersionString = MakeStaticString(versionString.str());
2260
2261 std::ostringstream shadingLanguageVersionString;
2262 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2263 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2264 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2265 << ")";
2266 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002267}
2268
Geoff Langcec35902014-04-16 10:52:36 -04002269void Context::initExtensionStrings()
2270{
Geoff Langc339c4e2016-11-29 10:37:36 -05002271 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2272 std::ostringstream combinedStringStream;
2273 std::copy(strings.begin(), strings.end(),
2274 std::ostream_iterator<const char *>(combinedStringStream, " "));
2275 return MakeStaticString(combinedStringStream.str());
2276 };
2277
2278 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002279 for (const auto &extensionString : mExtensions.getStrings())
2280 {
2281 mExtensionStrings.push_back(MakeStaticString(extensionString));
2282 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002283 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002284
Bryan Bernhart58806562017-01-05 13:09:31 -08002285 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2286
Geoff Langc339c4e2016-11-29 10:37:36 -05002287 mRequestableExtensionStrings.clear();
2288 for (const auto &extensionInfo : GetExtensionInfoMap())
2289 {
2290 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002291 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2292 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002293 {
2294 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2295 }
2296 }
2297 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002298}
2299
Geoff Langc339c4e2016-11-29 10:37:36 -05002300const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002301{
Geoff Langc339c4e2016-11-29 10:37:36 -05002302 switch (name)
2303 {
2304 case GL_VENDOR:
2305 return reinterpret_cast<const GLubyte *>("Google Inc.");
2306
2307 case GL_RENDERER:
2308 return reinterpret_cast<const GLubyte *>(mRendererString);
2309
2310 case GL_VERSION:
2311 return reinterpret_cast<const GLubyte *>(mVersionString);
2312
2313 case GL_SHADING_LANGUAGE_VERSION:
2314 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2315
2316 case GL_EXTENSIONS:
2317 return reinterpret_cast<const GLubyte *>(mExtensionString);
2318
2319 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2320 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2321
2322 default:
2323 UNREACHABLE();
2324 return nullptr;
2325 }
Geoff Langcec35902014-04-16 10:52:36 -04002326}
2327
Geoff Langc339c4e2016-11-29 10:37:36 -05002328const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002329{
Geoff Langc339c4e2016-11-29 10:37:36 -05002330 switch (name)
2331 {
2332 case GL_EXTENSIONS:
2333 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2334
2335 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2336 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2337
2338 default:
2339 UNREACHABLE();
2340 return nullptr;
2341 }
Geoff Langcec35902014-04-16 10:52:36 -04002342}
2343
2344size_t Context::getExtensionStringCount() const
2345{
2346 return mExtensionStrings.size();
2347}
2348
Geoff Langc339c4e2016-11-29 10:37:36 -05002349void Context::requestExtension(const char *name)
2350{
2351 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2352 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2353 const auto &extension = extensionInfos.at(name);
2354 ASSERT(extension.Requestable);
2355
2356 if (mExtensions.*(extension.ExtensionsMember))
2357 {
2358 // Extension already enabled
2359 return;
2360 }
2361
2362 mExtensions.*(extension.ExtensionsMember) = true;
2363 updateCaps();
2364 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002365
2366 // Re-create the compiler with the requested extensions enabled.
2367 SafeDelete(mCompiler);
2368 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002369}
2370
2371size_t Context::getRequestableExtensionStringCount() const
2372{
2373 return mRequestableExtensionStrings.size();
2374}
2375
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002376void Context::beginTransformFeedback(GLenum primitiveMode)
2377{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002378 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002379 ASSERT(transformFeedback != nullptr);
2380 ASSERT(!transformFeedback->isPaused());
2381
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002382 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002383}
2384
2385bool Context::hasActiveTransformFeedback(GLuint program) const
2386{
2387 for (auto pair : mTransformFeedbackMap)
2388 {
2389 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2390 {
2391 return true;
2392 }
2393 }
2394 return false;
2395}
2396
Corentin Wallezc295e512017-01-27 17:47:50 -05002397void Context::initCaps(bool webGLContext, const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002398{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002399 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002400
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002401 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002402
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002403 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002404
Geoff Langeb66a6e2016-10-31 13:06:12 -04002405 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002406 {
2407 // Disable ES3+ extensions
2408 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002409 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002410 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002411 }
2412
Geoff Langeb66a6e2016-10-31 13:06:12 -04002413 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002414 {
2415 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2416 //mExtensions.sRGB = false;
2417 }
2418
Jamie Madill00ed7a12016-05-19 13:13:38 -04002419 // Some extensions are always available because they are implemented in the GL layer.
2420 mExtensions.bindUniformLocation = true;
2421 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002422 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002423 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002424
2425 // Enable the no error extension if the context was created with the flag.
2426 mExtensions.noError = mSkipValidation;
2427
Corentin Wallezccab69d2017-01-27 16:57:15 -05002428 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002429 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002430
Geoff Lang70d0f492015-12-10 17:45:46 -05002431 // Explicitly enable GL_KHR_debug
2432 mExtensions.debug = true;
2433 mExtensions.maxDebugMessageLength = 1024;
2434 mExtensions.maxDebugLoggedMessages = 1024;
2435 mExtensions.maxDebugGroupStackDepth = 1024;
2436 mExtensions.maxLabelLength = 1024;
2437
Geoff Langff5b2d52016-09-07 11:32:23 -04002438 // Explicitly enable GL_ANGLE_robust_client_memory
2439 mExtensions.robustClientMemory = true;
2440
Geoff Lang301d1612014-07-09 10:34:37 -04002441 // Apply implementation limits
2442 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002443 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2444 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2445
2446 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002447
Geoff Langc287ea62016-09-16 14:46:51 -04002448 // WebGL compatibility
2449 mExtensions.webglCompatibility = webGLContext;
2450 for (const auto &extensionInfo : GetExtensionInfoMap())
2451 {
2452 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002453 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002454 {
2455 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2456 }
2457 }
2458
2459 // Generate texture caps
2460 updateCaps();
2461}
2462
2463void Context::updateCaps()
2464{
Geoff Lang900013c2014-07-07 11:32:19 -04002465 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002466 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002467
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002468 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002469 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2470 {
2471 GLenum format = i->first;
2472 TextureCaps formatCaps = i->second;
2473
Geoff Lang5d601382014-07-22 15:14:06 -04002474 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002475
Geoff Lang0d8b7242015-09-09 14:56:53 -04002476 // Update the format caps based on the client version and extensions.
2477 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2478 // ES3.
2479 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002480 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002481 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002482 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002483 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002484 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002485
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002486 // OpenGL ES does not support multisampling with non-rendererable formats
2487 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2488 if (!formatInfo.renderSupport ||
2489 (getClientVersion() < ES_3_1 &&
2490 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002491 {
Geoff Langd87878e2014-09-19 15:42:59 -04002492 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002493 }
Geoff Langd87878e2014-09-19 15:42:59 -04002494
2495 if (formatCaps.texturable && formatInfo.compressed)
2496 {
2497 mCaps.compressedTextureFormats.push_back(format);
2498 }
2499
2500 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002501 }
2502}
2503
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002504void Context::initWorkarounds()
2505{
2506 // Lose the context upon out of memory error if the application is
2507 // expecting to watch for those events.
2508 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2509}
2510
Jamie Madill1b94d432015-08-07 13:23:23 -04002511void Context::syncRendererState()
2512{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002513 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2514 mImplementation->syncState(mGLState, dirtyBits);
2515 mGLState.clearDirtyBits();
2516 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002517}
2518
Jamie Madillad9f24e2016-02-12 09:27:24 -05002519void Context::syncRendererState(const State::DirtyBits &bitMask,
2520 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002521{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002522 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2523 mImplementation->syncState(mGLState, dirtyBits);
2524 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002525
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002526 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002527}
Jamie Madillc29968b2016-01-20 11:17:23 -05002528
2529void Context::blitFramebuffer(GLint srcX0,
2530 GLint srcY0,
2531 GLint srcX1,
2532 GLint srcY1,
2533 GLint dstX0,
2534 GLint dstY0,
2535 GLint dstX1,
2536 GLint dstY1,
2537 GLbitfield mask,
2538 GLenum filter)
2539{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002540 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002541 ASSERT(drawFramebuffer);
2542
2543 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2544 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2545
Jamie Madillad9f24e2016-02-12 09:27:24 -05002546 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002547
Jamie Madill8415b5f2016-04-26 13:41:39 -04002548 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002549}
Jamie Madillc29968b2016-01-20 11:17:23 -05002550
2551void Context::clear(GLbitfield mask)
2552{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002553 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002554 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002555}
2556
2557void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2558{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002559 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002560 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2561 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002562}
2563
2564void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2565{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002566 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002567 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2568 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002569}
2570
2571void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2572{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002573 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002574 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2575 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002576}
2577
2578void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2579{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002580 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002581 ASSERT(framebufferObject);
2582
2583 // If a buffer is not present, the clear has no effect
2584 if (framebufferObject->getDepthbuffer() == nullptr &&
2585 framebufferObject->getStencilbuffer() == nullptr)
2586 {
2587 return;
2588 }
2589
Jamie Madillad9f24e2016-02-12 09:27:24 -05002590 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002591 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2592 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002593}
2594
2595void Context::readPixels(GLint x,
2596 GLint y,
2597 GLsizei width,
2598 GLsizei height,
2599 GLenum format,
2600 GLenum type,
2601 GLvoid *pixels)
2602{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002603 if (width == 0 || height == 0)
2604 {
2605 return;
2606 }
2607
Jamie Madillad9f24e2016-02-12 09:27:24 -05002608 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002609
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002610 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002611 ASSERT(framebufferObject);
2612
2613 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002614 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002615}
2616
2617void Context::copyTexImage2D(GLenum target,
2618 GLint level,
2619 GLenum internalformat,
2620 GLint x,
2621 GLint y,
2622 GLsizei width,
2623 GLsizei height,
2624 GLint border)
2625{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002626 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002627 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002628
Jamie Madillc29968b2016-01-20 11:17:23 -05002629 Rectangle sourceArea(x, y, width, height);
2630
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002631 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002632 Texture *texture =
2633 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002634 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002635}
2636
2637void Context::copyTexSubImage2D(GLenum target,
2638 GLint level,
2639 GLint xoffset,
2640 GLint yoffset,
2641 GLint x,
2642 GLint y,
2643 GLsizei width,
2644 GLsizei height)
2645{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002646 if (width == 0 || height == 0)
2647 {
2648 return;
2649 }
2650
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002651 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002652 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002653
Jamie Madillc29968b2016-01-20 11:17:23 -05002654 Offset destOffset(xoffset, yoffset, 0);
2655 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 Madill8897afa2017-02-06 17:17:23 -05002660 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002661}
2662
2663void Context::copyTexSubImage3D(GLenum target,
2664 GLint level,
2665 GLint xoffset,
2666 GLint yoffset,
2667 GLint zoffset,
2668 GLint x,
2669 GLint y,
2670 GLsizei width,
2671 GLsizei height)
2672{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002673 if (width == 0 || height == 0)
2674 {
2675 return;
2676 }
2677
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002678 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002679 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002680
Jamie Madillc29968b2016-01-20 11:17:23 -05002681 Offset destOffset(xoffset, yoffset, zoffset);
2682 Rectangle sourceArea(x, y, width, height);
2683
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002684 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002685 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002686 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002687}
2688
2689void Context::framebufferTexture2D(GLenum target,
2690 GLenum attachment,
2691 GLenum textarget,
2692 GLuint texture,
2693 GLint level)
2694{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002695 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002696 ASSERT(framebuffer);
2697
2698 if (texture != 0)
2699 {
2700 Texture *textureObj = getTexture(texture);
2701
2702 ImageIndex index = ImageIndex::MakeInvalid();
2703
2704 if (textarget == GL_TEXTURE_2D)
2705 {
2706 index = ImageIndex::Make2D(level);
2707 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002708 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2709 {
2710 ASSERT(level == 0);
2711 index = ImageIndex::Make2DMultisample();
2712 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002713 else
2714 {
2715 ASSERT(IsCubeMapTextureTarget(textarget));
2716 index = ImageIndex::MakeCube(textarget, level);
2717 }
2718
2719 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2720 }
2721 else
2722 {
2723 framebuffer->resetAttachment(attachment);
2724 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002725
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002726 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002727}
2728
2729void Context::framebufferRenderbuffer(GLenum target,
2730 GLenum attachment,
2731 GLenum renderbuffertarget,
2732 GLuint renderbuffer)
2733{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002734 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002735 ASSERT(framebuffer);
2736
2737 if (renderbuffer != 0)
2738 {
2739 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2740 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2741 renderbufferObject);
2742 }
2743 else
2744 {
2745 framebuffer->resetAttachment(attachment);
2746 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002747
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002748 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002749}
2750
2751void Context::framebufferTextureLayer(GLenum target,
2752 GLenum attachment,
2753 GLuint texture,
2754 GLint level,
2755 GLint layer)
2756{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002757 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002758 ASSERT(framebuffer);
2759
2760 if (texture != 0)
2761 {
2762 Texture *textureObject = getTexture(texture);
2763
2764 ImageIndex index = ImageIndex::MakeInvalid();
2765
2766 if (textureObject->getTarget() == GL_TEXTURE_3D)
2767 {
2768 index = ImageIndex::Make3D(level, layer);
2769 }
2770 else
2771 {
2772 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2773 index = ImageIndex::Make2DArray(level, layer);
2774 }
2775
2776 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2777 }
2778 else
2779 {
2780 framebuffer->resetAttachment(attachment);
2781 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002782
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002783 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002784}
2785
2786void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2787{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002788 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002789 ASSERT(framebuffer);
2790 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002791 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002792}
2793
2794void Context::readBuffer(GLenum mode)
2795{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002796 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002797 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002798 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002799}
2800
2801void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2802{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002803 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002804 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002805
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002806 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002807 ASSERT(framebuffer);
2808
2809 // The specification isn't clear what should be done when the framebuffer isn't complete.
2810 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002811 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002812}
2813
2814void Context::invalidateFramebuffer(GLenum target,
2815 GLsizei numAttachments,
2816 const GLenum *attachments)
2817{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002818 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002820
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002821 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002822 ASSERT(framebuffer);
2823
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002824 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002825 {
Jamie Madill437fa652016-05-03 15:13:24 -04002826 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002827 }
Jamie Madill437fa652016-05-03 15:13:24 -04002828
2829 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002830}
2831
2832void Context::invalidateSubFramebuffer(GLenum target,
2833 GLsizei numAttachments,
2834 const GLenum *attachments,
2835 GLint x,
2836 GLint y,
2837 GLsizei width,
2838 GLsizei height)
2839{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002840 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002841 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002842
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002843 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002844 ASSERT(framebuffer);
2845
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002846 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002847 {
Jamie Madill437fa652016-05-03 15:13:24 -04002848 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002849 }
Jamie Madill437fa652016-05-03 15:13:24 -04002850
2851 Rectangle area(x, y, width, height);
2852 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002853}
2854
Jamie Madill73a84962016-02-12 09:27:23 -05002855void Context::texImage2D(GLenum target,
2856 GLint level,
2857 GLint internalformat,
2858 GLsizei width,
2859 GLsizei height,
2860 GLint border,
2861 GLenum format,
2862 GLenum type,
2863 const GLvoid *pixels)
2864{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002865 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002866
2867 Extents size(width, height, 1);
2868 Texture *texture =
2869 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002870 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2871 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002872}
2873
2874void Context::texImage3D(GLenum target,
2875 GLint level,
2876 GLint internalformat,
2877 GLsizei width,
2878 GLsizei height,
2879 GLsizei depth,
2880 GLint border,
2881 GLenum format,
2882 GLenum type,
2883 const GLvoid *pixels)
2884{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002885 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002886
2887 Extents size(width, height, depth);
2888 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002889 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2890 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002891}
2892
2893void Context::texSubImage2D(GLenum target,
2894 GLint level,
2895 GLint xoffset,
2896 GLint yoffset,
2897 GLsizei width,
2898 GLsizei height,
2899 GLenum format,
2900 GLenum type,
2901 const GLvoid *pixels)
2902{
2903 // Zero sized uploads are valid but no-ops
2904 if (width == 0 || height == 0)
2905 {
2906 return;
2907 }
2908
Jamie Madillad9f24e2016-02-12 09:27:24 -05002909 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002910
2911 Box area(xoffset, yoffset, 0, width, height, 1);
2912 Texture *texture =
2913 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002914 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2915 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002916}
2917
2918void Context::texSubImage3D(GLenum target,
2919 GLint level,
2920 GLint xoffset,
2921 GLint yoffset,
2922 GLint zoffset,
2923 GLsizei width,
2924 GLsizei height,
2925 GLsizei depth,
2926 GLenum format,
2927 GLenum type,
2928 const GLvoid *pixels)
2929{
2930 // Zero sized uploads are valid but no-ops
2931 if (width == 0 || height == 0 || depth == 0)
2932 {
2933 return;
2934 }
2935
Jamie Madillad9f24e2016-02-12 09:27:24 -05002936 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002937
2938 Box area(xoffset, yoffset, zoffset, width, height, depth);
2939 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002940 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2941 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002942}
2943
2944void Context::compressedTexImage2D(GLenum target,
2945 GLint level,
2946 GLenum internalformat,
2947 GLsizei width,
2948 GLsizei height,
2949 GLint border,
2950 GLsizei imageSize,
2951 const GLvoid *data)
2952{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002953 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002954
2955 Extents size(width, height, 1);
2956 Texture *texture =
2957 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002958 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002959 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002960 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002961}
2962
2963void Context::compressedTexImage3D(GLenum target,
2964 GLint level,
2965 GLenum internalformat,
2966 GLsizei width,
2967 GLsizei height,
2968 GLsizei depth,
2969 GLint border,
2970 GLsizei imageSize,
2971 const GLvoid *data)
2972{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002973 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002974
2975 Extents size(width, height, depth);
2976 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002977 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002978 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002979 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002980}
2981
2982void Context::compressedTexSubImage2D(GLenum target,
2983 GLint level,
2984 GLint xoffset,
2985 GLint yoffset,
2986 GLsizei width,
2987 GLsizei height,
2988 GLenum format,
2989 GLsizei imageSize,
2990 const GLvoid *data)
2991{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002992 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002993
2994 Box area(xoffset, yoffset, 0, width, height, 1);
2995 Texture *texture =
2996 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002997 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002998 format, imageSize,
2999 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003000}
3001
3002void Context::compressedTexSubImage3D(GLenum target,
3003 GLint level,
3004 GLint xoffset,
3005 GLint yoffset,
3006 GLint zoffset,
3007 GLsizei width,
3008 GLsizei height,
3009 GLsizei depth,
3010 GLenum format,
3011 GLsizei imageSize,
3012 const GLvoid *data)
3013{
3014 // Zero sized uploads are valid but no-ops
3015 if (width == 0 || height == 0)
3016 {
3017 return;
3018 }
3019
Jamie Madillad9f24e2016-02-12 09:27:24 -05003020 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003021
3022 Box area(xoffset, yoffset, zoffset, width, height, depth);
3023 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003024 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003025 format, imageSize,
3026 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003027}
3028
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003029void Context::generateMipmap(GLenum target)
3030{
3031 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003032 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003033}
3034
Geoff Lang97073d12016-04-20 10:42:34 -07003035void Context::copyTextureCHROMIUM(GLuint sourceId,
3036 GLuint destId,
3037 GLint internalFormat,
3038 GLenum destType,
3039 GLboolean unpackFlipY,
3040 GLboolean unpackPremultiplyAlpha,
3041 GLboolean unpackUnmultiplyAlpha)
3042{
3043 syncStateForTexImage();
3044
3045 gl::Texture *sourceTexture = getTexture(sourceId);
3046 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003047 handleError(destTexture->copyTexture(this, internalFormat, destType, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003048 unpackPremultiplyAlpha == GL_TRUE,
3049 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3050}
3051
3052void Context::copySubTextureCHROMIUM(GLuint sourceId,
3053 GLuint destId,
3054 GLint xoffset,
3055 GLint yoffset,
3056 GLint x,
3057 GLint y,
3058 GLsizei width,
3059 GLsizei height,
3060 GLboolean unpackFlipY,
3061 GLboolean unpackPremultiplyAlpha,
3062 GLboolean unpackUnmultiplyAlpha)
3063{
3064 // Zero sized copies are valid but no-ops
3065 if (width == 0 || height == 0)
3066 {
3067 return;
3068 }
3069
3070 syncStateForTexImage();
3071
3072 gl::Texture *sourceTexture = getTexture(sourceId);
3073 gl::Texture *destTexture = getTexture(destId);
3074 Offset offset(xoffset, yoffset, 0);
3075 Rectangle area(x, y, width, height);
Jamie Madill8897afa2017-02-06 17:17:23 -05003076 handleError(destTexture->copySubTexture(this, offset, area, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003077 unpackPremultiplyAlpha == GL_TRUE,
3078 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3079}
3080
Geoff Lang47110bf2016-04-20 11:13:22 -07003081void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3082{
3083 syncStateForTexImage();
3084
3085 gl::Texture *sourceTexture = getTexture(sourceId);
3086 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003087 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003088}
3089
Geoff Lang496c02d2016-10-20 11:38:11 -07003090void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003091{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003092 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003093 ASSERT(buffer);
3094
Geoff Lang496c02d2016-10-20 11:38:11 -07003095 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003096}
3097
3098GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3099{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003100 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003101 ASSERT(buffer);
3102
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003103 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003104 if (error.isError())
3105 {
Jamie Madill437fa652016-05-03 15:13:24 -04003106 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003107 return nullptr;
3108 }
3109
3110 return buffer->getMapPointer();
3111}
3112
3113GLboolean Context::unmapBuffer(GLenum target)
3114{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003115 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003116 ASSERT(buffer);
3117
3118 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003119 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003120 if (error.isError())
3121 {
Jamie Madill437fa652016-05-03 15:13:24 -04003122 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003123 return GL_FALSE;
3124 }
3125
3126 return result;
3127}
3128
3129GLvoid *Context::mapBufferRange(GLenum target,
3130 GLintptr offset,
3131 GLsizeiptr length,
3132 GLbitfield access)
3133{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003134 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003135 ASSERT(buffer);
3136
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003137 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003138 if (error.isError())
3139 {
Jamie Madill437fa652016-05-03 15:13:24 -04003140 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003141 return nullptr;
3142 }
3143
3144 return buffer->getMapPointer();
3145}
3146
3147void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3148{
3149 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3150}
3151
Jamie Madillad9f24e2016-02-12 09:27:24 -05003152void Context::syncStateForReadPixels()
3153{
3154 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3155}
3156
3157void Context::syncStateForTexImage()
3158{
3159 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3160}
3161
3162void Context::syncStateForClear()
3163{
3164 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3165}
3166
3167void Context::syncStateForBlit()
3168{
3169 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3170}
3171
Jamie Madillc20ab272016-06-09 07:20:46 -07003172void Context::activeTexture(GLenum texture)
3173{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003174 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003175}
3176
3177void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3178{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003179 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003180}
3181
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003182void Context::blendEquation(GLenum mode)
3183{
3184 mGLState.setBlendEquation(mode, mode);
3185}
3186
Jamie Madillc20ab272016-06-09 07:20:46 -07003187void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3188{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003189 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003190}
3191
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003192void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3193{
3194 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3195}
3196
Jamie Madillc20ab272016-06-09 07:20:46 -07003197void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3198{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003199 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003200}
3201
3202void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3203{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003204 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003205}
3206
3207void Context::clearDepthf(GLclampf depth)
3208{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003209 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003210}
3211
3212void Context::clearStencil(GLint s)
3213{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003214 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003215}
3216
3217void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3218{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003219 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003220}
3221
3222void Context::cullFace(GLenum mode)
3223{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003224 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003225}
3226
3227void Context::depthFunc(GLenum func)
3228{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003229 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003230}
3231
3232void Context::depthMask(GLboolean flag)
3233{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003234 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003235}
3236
3237void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3238{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003239 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003240}
3241
3242void Context::disable(GLenum cap)
3243{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003244 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003245}
3246
3247void Context::disableVertexAttribArray(GLuint index)
3248{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003249 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003250}
3251
3252void Context::enable(GLenum cap)
3253{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003254 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003255}
3256
3257void Context::enableVertexAttribArray(GLuint index)
3258{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003259 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003260}
3261
3262void Context::frontFace(GLenum mode)
3263{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003264 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003265}
3266
3267void Context::hint(GLenum target, GLenum mode)
3268{
3269 switch (target)
3270 {
3271 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003272 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003273 break;
3274
3275 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003276 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003277 break;
3278
3279 default:
3280 UNREACHABLE();
3281 return;
3282 }
3283}
3284
3285void Context::lineWidth(GLfloat width)
3286{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003287 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003288}
3289
3290void Context::pixelStorei(GLenum pname, GLint param)
3291{
3292 switch (pname)
3293 {
3294 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003295 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003296 break;
3297
3298 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003299 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003300 break;
3301
3302 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003303 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003304 break;
3305
3306 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003307 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003308 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003309 break;
3310
3311 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003312 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003313 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003314 break;
3315
3316 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003317 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003318 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003319 break;
3320
3321 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003322 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003323 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003324 break;
3325
3326 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003327 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003328 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003329 break;
3330
3331 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003332 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003333 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003334 break;
3335
3336 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003337 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003338 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003339 break;
3340
3341 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003342 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003343 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003344 break;
3345
3346 default:
3347 UNREACHABLE();
3348 return;
3349 }
3350}
3351
3352void Context::polygonOffset(GLfloat factor, GLfloat units)
3353{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003355}
3356
3357void Context::sampleCoverage(GLclampf value, GLboolean invert)
3358{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003359 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003360}
3361
3362void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3363{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365}
3366
3367void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3368{
3369 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3370 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003371 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003372 }
3373
3374 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3375 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003376 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003377 }
3378}
3379
3380void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3381{
3382 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3383 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003384 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003385 }
3386
3387 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3388 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003390 }
3391}
3392
3393void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3394{
3395 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3396 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003397 mGLState.setStencilOperations(fail, zfail, zpass);
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.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003403 }
3404}
3405
3406void Context::vertexAttrib1f(GLuint index, GLfloat x)
3407{
3408 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003409 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003410}
3411
3412void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3413{
3414 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003415 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003416}
3417
3418void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3419{
3420 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003421 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003422}
3423
3424void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3425{
3426 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003427 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003428}
3429
3430void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3431{
3432 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003433 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003434}
3435
3436void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3437{
3438 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003439 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003440}
3441
3442void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3443{
3444 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003445 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003446}
3447
3448void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3449{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003450 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003451}
3452
3453void Context::vertexAttribPointer(GLuint index,
3454 GLint size,
3455 GLenum type,
3456 GLboolean normalized,
3457 GLsizei stride,
3458 const GLvoid *ptr)
3459{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003460 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3461 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003462}
3463
3464void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3465{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003466 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003467}
3468
3469void Context::vertexAttribIPointer(GLuint index,
3470 GLint size,
3471 GLenum type,
3472 GLsizei stride,
3473 const GLvoid *pointer)
3474{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003475 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3476 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003477}
3478
3479void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3480{
3481 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003482 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003483}
3484
3485void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3486{
3487 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003488 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003489}
3490
3491void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3492{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003493 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003494}
3495
3496void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3497{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003498 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003499}
3500
3501void Context::debugMessageControl(GLenum source,
3502 GLenum type,
3503 GLenum severity,
3504 GLsizei count,
3505 const GLuint *ids,
3506 GLboolean enabled)
3507{
3508 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003509 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3510 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003511}
3512
3513void Context::debugMessageInsert(GLenum source,
3514 GLenum type,
3515 GLuint id,
3516 GLenum severity,
3517 GLsizei length,
3518 const GLchar *buf)
3519{
3520 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003521 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003522}
3523
3524void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3525{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003526 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003527}
3528
3529GLuint Context::getDebugMessageLog(GLuint count,
3530 GLsizei bufSize,
3531 GLenum *sources,
3532 GLenum *types,
3533 GLuint *ids,
3534 GLenum *severities,
3535 GLsizei *lengths,
3536 GLchar *messageLog)
3537{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003538 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3539 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003540}
3541
3542void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3543{
3544 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003545 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003546}
3547
3548void Context::popDebugGroup()
3549{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003551}
3552
Jamie Madill29639852016-09-02 15:00:09 -04003553void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3554{
3555 Buffer *buffer = mGLState.getTargetBuffer(target);
3556 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003557 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003558}
3559
3560void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3561{
3562 if (data == nullptr)
3563 {
3564 return;
3565 }
3566
3567 Buffer *buffer = mGLState.getTargetBuffer(target);
3568 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003569 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003570}
3571
Jamie Madillef300b12016-10-07 15:12:09 -04003572void Context::attachShader(GLuint program, GLuint shader)
3573{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003574 auto programObject = mState.mShaderPrograms->getProgram(program);
3575 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003576 ASSERT(programObject && shaderObject);
3577 programObject->attachShader(shaderObject);
3578}
3579
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003580const Workarounds &Context::getWorkarounds() const
3581{
3582 return mWorkarounds;
3583}
3584
Jamie Madillb0817d12016-11-01 15:48:31 -04003585void Context::copyBufferSubData(GLenum readTarget,
3586 GLenum writeTarget,
3587 GLintptr readOffset,
3588 GLintptr writeOffset,
3589 GLsizeiptr size)
3590{
3591 // if size is zero, the copy is a successful no-op
3592 if (size == 0)
3593 {
3594 return;
3595 }
3596
3597 // TODO(jmadill): cache these.
3598 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3599 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3600
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003601 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003602}
3603
Jamie Madill01a80ee2016-11-07 12:06:18 -05003604void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3605{
3606 Program *programObject = getProgram(program);
3607 // TODO(jmadill): Re-use this from the validation if possible.
3608 ASSERT(programObject);
3609 programObject->bindAttributeLocation(index, name);
3610}
3611
3612void Context::bindBuffer(GLenum target, GLuint buffer)
3613{
3614 switch (target)
3615 {
3616 case GL_ARRAY_BUFFER:
3617 bindArrayBuffer(buffer);
3618 break;
3619 case GL_ELEMENT_ARRAY_BUFFER:
3620 bindElementArrayBuffer(buffer);
3621 break;
3622 case GL_COPY_READ_BUFFER:
3623 bindCopyReadBuffer(buffer);
3624 break;
3625 case GL_COPY_WRITE_BUFFER:
3626 bindCopyWriteBuffer(buffer);
3627 break;
3628 case GL_PIXEL_PACK_BUFFER:
3629 bindPixelPackBuffer(buffer);
3630 break;
3631 case GL_PIXEL_UNPACK_BUFFER:
3632 bindPixelUnpackBuffer(buffer);
3633 break;
3634 case GL_UNIFORM_BUFFER:
3635 bindGenericUniformBuffer(buffer);
3636 break;
3637 case GL_TRANSFORM_FEEDBACK_BUFFER:
3638 bindGenericTransformFeedbackBuffer(buffer);
3639 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003640 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003641 if (buffer != 0)
3642 {
3643 // Binding buffers to this binding point is not implemented yet.
3644 UNIMPLEMENTED();
3645 }
Geoff Lang3b573612016-10-31 14:08:10 -04003646 break;
3647 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003648 if (buffer != 0)
3649 {
3650 // Binding buffers to this binding point is not implemented yet.
3651 UNIMPLEMENTED();
3652 }
Geoff Lang3b573612016-10-31 14:08:10 -04003653 break;
3654 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003655 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003656 break;
3657 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003658 if (buffer != 0)
3659 {
3660 // Binding buffers to this binding point is not implemented yet.
3661 UNIMPLEMENTED();
3662 }
Geoff Lang3b573612016-10-31 14:08:10 -04003663 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003664
3665 default:
3666 UNREACHABLE();
3667 break;
3668 }
3669}
3670
3671void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3672{
3673 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3674 {
3675 bindReadFramebuffer(framebuffer);
3676 }
3677
3678 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3679 {
3680 bindDrawFramebuffer(framebuffer);
3681 }
3682}
3683
3684void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3685{
3686 ASSERT(target == GL_RENDERBUFFER);
3687 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003688 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003689 mGLState.setRenderbufferBinding(object);
3690}
3691
JiangYizhoubddc46b2016-12-09 09:50:51 +08003692void Context::texStorage2DMultisample(GLenum target,
3693 GLsizei samples,
3694 GLenum internalformat,
3695 GLsizei width,
3696 GLsizei height,
3697 GLboolean fixedsamplelocations)
3698{
3699 Extents size(width, height, 1);
3700 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003701 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003702 fixedsamplelocations));
3703}
3704
3705void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3706{
3707 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3708 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3709
3710 switch (pname)
3711 {
3712 case GL_SAMPLE_POSITION:
3713 handleError(framebuffer->getSamplePosition(index, val));
3714 break;
3715 default:
3716 UNREACHABLE();
3717 }
3718}
3719
Jamie Madillc29968b2016-01-20 11:17:23 -05003720} // namespace gl