blob: 0f6a15b5f8ef93a64d88b0b798bb02866c500544 [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 Madill6c1f6712017-02-14 19:08:04 -0500388 mGLState.reset(this);
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 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500412 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500413 }
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);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500427
428 mState.mBuffers->release(this);
429 mState.mShaderPrograms->release(this);
430 mState.mTextures->release(this);
431 mState.mRenderbuffers->release(this);
432 mState.mSamplers->release(this);
433 mState.mFenceSyncs->release(this);
434 mState.mPaths->release(this);
435 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000436}
437
Jamie Madill70ee0f62017-02-06 16:04:20 -0500438Context::~Context()
439{
440}
441
442void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000443{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000444 if (!mHasBeenCurrent)
445 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000446 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500447 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400448 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000449
Corentin Wallezc295e512017-01-27 17:47:50 -0500450 int width = 0;
451 int height = 0;
452 if (surface != nullptr)
453 {
454 width = surface->getWidth();
455 height = surface->getHeight();
456 }
457
458 mGLState.setViewportParams(0, 0, width, height);
459 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000460
461 mHasBeenCurrent = true;
462 }
463
Jamie Madill1b94d432015-08-07 13:23:23 -0400464 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700465 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400466
Jamie Madill70ee0f62017-02-06 16:04:20 -0500467 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500468
469 Framebuffer *newDefault = nullptr;
470 if (surface != nullptr)
471 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500472 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500473 mCurrentSurface = surface;
474 newDefault = surface->getDefaultFramebuffer();
475 }
476 else
477 {
478 if (mSurfacelessFramebuffer == nullptr)
479 {
480 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
481 }
482
483 newDefault = mSurfacelessFramebuffer;
484 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000485
Corentin Wallez37c39792015-08-20 14:19:46 -0400486 // Update default framebuffer, the binding of the previous default
487 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400488 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700489 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400490 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700491 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400492 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700493 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400494 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700495 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400496 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500497 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400498 }
Ian Ewell292f0052016-02-04 10:37:32 -0500499
500 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700501 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000502}
503
Jamie Madill70ee0f62017-02-06 16:04:20 -0500504void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400505{
Corentin Wallez37c39792015-08-20 14:19:46 -0400506 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500507 Framebuffer *currentDefault = nullptr;
508 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400509 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500510 currentDefault = mCurrentSurface->getDefaultFramebuffer();
511 }
512 else if (mSurfacelessFramebuffer != nullptr)
513 {
514 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400515 }
516
Corentin Wallezc295e512017-01-27 17:47:50 -0500517 if (mGLState.getReadFramebuffer() == currentDefault)
518 {
519 mGLState.setReadFramebufferBinding(nullptr);
520 }
521 if (mGLState.getDrawFramebuffer() == currentDefault)
522 {
523 mGLState.setDrawFramebufferBinding(nullptr);
524 }
525 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
526
527 if (mCurrentSurface)
528 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500529 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500530 mCurrentSurface = nullptr;
531 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400532}
533
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000534GLuint Context::createBuffer()
535{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500536 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000537}
538
539GLuint Context::createProgram()
540{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500541 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000542}
543
544GLuint Context::createShader(GLenum type)
545{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500546 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000547}
548
549GLuint Context::createTexture()
550{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500551 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000552}
553
554GLuint Context::createRenderbuffer()
555{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500556 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000557}
558
Geoff Lang882033e2014-09-30 11:26:07 -0400559GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400560{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500561 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400562
Cooper Partind8e62a32015-01-29 15:21:25 -0800563 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400564}
565
Sami Väisänene45e53b2016-05-25 10:36:04 +0300566GLuint Context::createPaths(GLsizei range)
567{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500568 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300569 if (resultOrError.isError())
570 {
571 handleError(resultOrError.getError());
572 return 0;
573 }
574 return resultOrError.getResult();
575}
576
Jamie Madill57a89722013-07-02 11:57:03 -0400577GLuint Context::createVertexArray()
578{
Geoff Lang36167ab2015-12-07 10:27:14 -0500579 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
580 mVertexArrayMap[vertexArray] = nullptr;
581 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400582}
583
Jamie Madilldc356042013-07-19 16:36:57 -0400584GLuint Context::createSampler()
585{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500586 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400587}
588
Geoff Langc8058452014-02-03 12:04:11 -0500589GLuint Context::createTransformFeedback()
590{
Geoff Lang36167ab2015-12-07 10:27:14 -0500591 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
592 mTransformFeedbackMap[transformFeedback] = nullptr;
593 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500594}
595
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000596// Returns an unused framebuffer name
597GLuint Context::createFramebuffer()
598{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500599 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000600}
601
Jamie Madill33dc8432013-07-26 11:55:05 -0400602GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603{
Jamie Madill33dc8432013-07-26 11:55:05 -0400604 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000605
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400606 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000607
608 return handle;
609}
610
611// Returns an unused query name
612GLuint Context::createQuery()
613{
614 GLuint handle = mQueryHandleAllocator.allocate();
615
616 mQueryMap[handle] = NULL;
617
618 return handle;
619}
620
621void Context::deleteBuffer(GLuint buffer)
622{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500623 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000624 {
625 detachBuffer(buffer);
626 }
Jamie Madill893ab082014-05-16 16:56:10 -0400627
Jamie Madill6c1f6712017-02-14 19:08:04 -0500628 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629}
630
631void Context::deleteShader(GLuint shader)
632{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500633 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000634}
635
636void Context::deleteProgram(GLuint program)
637{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500638 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000639}
640
641void Context::deleteTexture(GLuint texture)
642{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500643 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000644 {
645 detachTexture(texture);
646 }
647
Jamie Madill6c1f6712017-02-14 19:08:04 -0500648 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000649}
650
651void Context::deleteRenderbuffer(GLuint renderbuffer)
652{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500653 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000654 {
655 detachRenderbuffer(renderbuffer);
656 }
Jamie Madill893ab082014-05-16 16:56:10 -0400657
Jamie Madill6c1f6712017-02-14 19:08:04 -0500658 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659}
660
Jamie Madillcd055f82013-07-26 11:55:15 -0400661void Context::deleteFenceSync(GLsync fenceSync)
662{
663 // The spec specifies the underlying Fence object is not deleted until all current
664 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
665 // and since our API is currently designed for being called from a single thread, we can delete
666 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500667 mState.mFenceSyncs->deleteObject(this,
668 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400669}
670
Sami Väisänene45e53b2016-05-25 10:36:04 +0300671void Context::deletePaths(GLuint first, GLsizei range)
672{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500673 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300674}
675
676bool Context::hasPathData(GLuint path) const
677{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500678 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300679 if (pathObj == nullptr)
680 return false;
681
682 return pathObj->hasPathData();
683}
684
685bool Context::hasPath(GLuint path) const
686{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500687 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300688}
689
690void Context::setPathCommands(GLuint path,
691 GLsizei numCommands,
692 const GLubyte *commands,
693 GLsizei numCoords,
694 GLenum coordType,
695 const void *coords)
696{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500697 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300698
699 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
700}
701
702void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
703{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500704 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300705
706 switch (pname)
707 {
708 case GL_PATH_STROKE_WIDTH_CHROMIUM:
709 pathObj->setStrokeWidth(value);
710 break;
711 case GL_PATH_END_CAPS_CHROMIUM:
712 pathObj->setEndCaps(static_cast<GLenum>(value));
713 break;
714 case GL_PATH_JOIN_STYLE_CHROMIUM:
715 pathObj->setJoinStyle(static_cast<GLenum>(value));
716 break;
717 case GL_PATH_MITER_LIMIT_CHROMIUM:
718 pathObj->setMiterLimit(value);
719 break;
720 case GL_PATH_STROKE_BOUND_CHROMIUM:
721 pathObj->setStrokeBound(value);
722 break;
723 default:
724 UNREACHABLE();
725 break;
726 }
727}
728
729void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
730{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500731 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300732
733 switch (pname)
734 {
735 case GL_PATH_STROKE_WIDTH_CHROMIUM:
736 *value = pathObj->getStrokeWidth();
737 break;
738 case GL_PATH_END_CAPS_CHROMIUM:
739 *value = static_cast<GLfloat>(pathObj->getEndCaps());
740 break;
741 case GL_PATH_JOIN_STYLE_CHROMIUM:
742 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
743 break;
744 case GL_PATH_MITER_LIMIT_CHROMIUM:
745 *value = pathObj->getMiterLimit();
746 break;
747 case GL_PATH_STROKE_BOUND_CHROMIUM:
748 *value = pathObj->getStrokeBound();
749 break;
750 default:
751 UNREACHABLE();
752 break;
753 }
754}
755
756void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
757{
758 mGLState.setPathStencilFunc(func, ref, mask);
759}
760
Jamie Madill57a89722013-07-02 11:57:03 -0400761void Context::deleteVertexArray(GLuint vertexArray)
762{
Geoff Lang36167ab2015-12-07 10:27:14 -0500763 auto iter = mVertexArrayMap.find(vertexArray);
764 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000765 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500766 VertexArray *vertexArrayObject = iter->second;
767 if (vertexArrayObject != nullptr)
768 {
769 detachVertexArray(vertexArray);
770 delete vertexArrayObject;
771 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000772
Geoff Lang36167ab2015-12-07 10:27:14 -0500773 mVertexArrayMap.erase(iter);
774 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400775 }
776}
777
Jamie Madilldc356042013-07-19 16:36:57 -0400778void Context::deleteSampler(GLuint sampler)
779{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500780 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400781 {
782 detachSampler(sampler);
783 }
784
Jamie Madill6c1f6712017-02-14 19:08:04 -0500785 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400786}
787
Geoff Langc8058452014-02-03 12:04:11 -0500788void Context::deleteTransformFeedback(GLuint transformFeedback)
789{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500790 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500791 if (iter != mTransformFeedbackMap.end())
792 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500793 TransformFeedback *transformFeedbackObject = iter->second;
794 if (transformFeedbackObject != nullptr)
795 {
796 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500797 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500798 }
799
Geoff Lang50b3fe82015-12-08 14:49:12 +0000800 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500801 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500802 }
803}
804
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805void Context::deleteFramebuffer(GLuint framebuffer)
806{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500807 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000808 {
809 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500811
Jamie Madill6c1f6712017-02-14 19:08:04 -0500812 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813}
814
Jamie Madill33dc8432013-07-26 11:55:05 -0400815void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500817 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000818
Jamie Madill33dc8432013-07-26 11:55:05 -0400819 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400821 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000822 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400823 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000824 }
825}
826
827void Context::deleteQuery(GLuint query)
828{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500829 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000830 if (queryObject != mQueryMap.end())
831 {
832 mQueryHandleAllocator.release(queryObject->first);
833 if (queryObject->second)
834 {
835 queryObject->second->release();
836 }
837 mQueryMap.erase(queryObject);
838 }
839}
840
Geoff Lang70d0f492015-12-10 17:45:46 -0500841Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000842{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500843 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000844}
845
Jamie Madill570f7c82014-07-03 10:38:54 -0400846Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500848 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849}
850
Geoff Lang70d0f492015-12-10 17:45:46 -0500851Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500853 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000854}
855
Jamie Madillcd055f82013-07-26 11:55:15 -0400856FenceSync *Context::getFenceSync(GLsync handle) const
857{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500858 return mState.mFenceSyncs->getFenceSync(
859 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400860}
861
Jamie Madill57a89722013-07-02 11:57:03 -0400862VertexArray *Context::getVertexArray(GLuint handle) const
863{
864 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500865 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400866}
867
Jamie Madilldc356042013-07-19 16:36:57 -0400868Sampler *Context::getSampler(GLuint handle) const
869{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500870 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400871}
872
Geoff Langc8058452014-02-03 12:04:11 -0500873TransformFeedback *Context::getTransformFeedback(GLuint handle) const
874{
Geoff Lang36167ab2015-12-07 10:27:14 -0500875 auto iter = mTransformFeedbackMap.find(handle);
876 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500877}
878
Geoff Lang70d0f492015-12-10 17:45:46 -0500879LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
880{
881 switch (identifier)
882 {
883 case GL_BUFFER:
884 return getBuffer(name);
885 case GL_SHADER:
886 return getShader(name);
887 case GL_PROGRAM:
888 return getProgram(name);
889 case GL_VERTEX_ARRAY:
890 return getVertexArray(name);
891 case GL_QUERY:
892 return getQuery(name);
893 case GL_TRANSFORM_FEEDBACK:
894 return getTransformFeedback(name);
895 case GL_SAMPLER:
896 return getSampler(name);
897 case GL_TEXTURE:
898 return getTexture(name);
899 case GL_RENDERBUFFER:
900 return getRenderbuffer(name);
901 case GL_FRAMEBUFFER:
902 return getFramebuffer(name);
903 default:
904 UNREACHABLE();
905 return nullptr;
906 }
907}
908
909LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
910{
911 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
912}
913
Martin Radev9d901792016-07-15 15:58:58 +0300914void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
915{
916 LabeledObject *object = getLabeledObject(identifier, name);
917 ASSERT(object != nullptr);
918
919 std::string labelName = GetObjectLabelFromPointer(length, label);
920 object->setLabel(labelName);
921}
922
923void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
924{
925 LabeledObject *object = getLabeledObjectFromPtr(ptr);
926 ASSERT(object != nullptr);
927
928 std::string labelName = GetObjectLabelFromPointer(length, label);
929 object->setLabel(labelName);
930}
931
932void Context::getObjectLabel(GLenum identifier,
933 GLuint name,
934 GLsizei bufSize,
935 GLsizei *length,
936 GLchar *label) const
937{
938 LabeledObject *object = getLabeledObject(identifier, name);
939 ASSERT(object != nullptr);
940
941 const std::string &objectLabel = object->getLabel();
942 GetObjectLabelBase(objectLabel, bufSize, length, label);
943}
944
945void Context::getObjectPtrLabel(const void *ptr,
946 GLsizei bufSize,
947 GLsizei *length,
948 GLchar *label) const
949{
950 LabeledObject *object = getLabeledObjectFromPtr(ptr);
951 ASSERT(object != nullptr);
952
953 const std::string &objectLabel = object->getLabel();
954 GetObjectLabelBase(objectLabel, bufSize, length, label);
955}
956
Jamie Madilldc356042013-07-19 16:36:57 -0400957bool Context::isSampler(GLuint samplerName) const
958{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500959 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400960}
961
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500962void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000963{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500964 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700965 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000966}
967
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800968void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
969{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500970 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800971 mGLState.setDrawIndirectBufferBinding(buffer);
972}
973
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500974void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000975{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500976 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700977 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978}
979
Jamie Madilldedd7b92014-11-05 16:30:36 -0500980void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500982 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000983
Jamie Madilldedd7b92014-11-05 16:30:36 -0500984 if (handle == 0)
985 {
986 texture = mZeroTextures[target].get();
987 }
988 else
989 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500990 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500991 }
992
993 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700994 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000995}
996
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500997void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000998{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500999 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1000 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001001 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001002}
1003
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001004void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001005{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001006 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1007 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001008 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001009}
1010
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001011void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001012{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001013 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001014 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001015}
1016
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001017void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001018{
Geoff Lang76b10c92014-09-05 16:28:14 -04001019 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001020 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001021 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001022 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001023}
1024
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001025void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +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.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001029}
1030
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001031void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1032 GLuint index,
1033 GLintptr offset,
1034 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001035{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001036 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001037 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001038}
1039
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001040void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +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()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001044}
1045
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001046void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1047 GLuint index,
1048 GLintptr offset,
1049 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001050{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001051 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001052 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001053}
1054
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001055void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001056{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001057 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001058 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001059}
1060
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001061void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001062{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001063 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001064 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001065}
1066
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001067void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001068{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001069 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001070 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001071}
1072
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001073void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001074{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001075 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001076 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001077}
1078
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001079void Context::useProgram(GLuint program)
1080{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001081 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001082}
1083
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001084void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001085{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001086 TransformFeedback *transformFeedback =
1087 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001088 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001089}
1090
Geoff Lang5aad9672014-09-08 11:10:42 -04001091Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001092{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001093 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001094 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095
Geoff Lang5aad9672014-09-08 11:10:42 -04001096 // begin query
1097 Error error = queryObject->begin();
1098 if (error.isError())
1099 {
1100 return error;
1101 }
1102
1103 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001104 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001105
He Yunchaoacd18982017-01-04 10:46:42 +08001106 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001107}
1108
Geoff Lang5aad9672014-09-08 11:10:42 -04001109Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001110{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001111 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001112 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001113
Geoff Lang5aad9672014-09-08 11:10:42 -04001114 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001115
Geoff Lang5aad9672014-09-08 11:10:42 -04001116 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001117 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001118
1119 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001120}
1121
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001122Error Context::queryCounter(GLuint id, GLenum target)
1123{
1124 ASSERT(target == GL_TIMESTAMP_EXT);
1125
1126 Query *queryObject = getQuery(id, true, target);
1127 ASSERT(queryObject);
1128
1129 return queryObject->queryCounter();
1130}
1131
1132void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1133{
1134 switch (pname)
1135 {
1136 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001137 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001138 break;
1139 case GL_QUERY_COUNTER_BITS_EXT:
1140 switch (target)
1141 {
1142 case GL_TIME_ELAPSED_EXT:
1143 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1144 break;
1145 case GL_TIMESTAMP_EXT:
1146 params[0] = getExtensions().queryCounterBitsTimestamp;
1147 break;
1148 default:
1149 UNREACHABLE();
1150 params[0] = 0;
1151 break;
1152 }
1153 break;
1154 default:
1155 UNREACHABLE();
1156 return;
1157 }
1158}
1159
Geoff Lang2186c382016-10-14 10:54:54 -04001160void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001161{
Geoff Lang2186c382016-10-14 10:54:54 -04001162 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001163}
1164
Geoff Lang2186c382016-10-14 10:54:54 -04001165void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001166{
Geoff Lang2186c382016-10-14 10:54:54 -04001167 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001168}
1169
Geoff Lang2186c382016-10-14 10:54:54 -04001170void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001171{
Geoff Lang2186c382016-10-14 10:54:54 -04001172 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001173}
1174
Geoff Lang2186c382016-10-14 10:54:54 -04001175void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001176{
Geoff Lang2186c382016-10-14 10:54:54 -04001177 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001178}
1179
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001180Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001182 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001183}
1184
Jamie Madill33dc8432013-07-26 11:55:05 -04001185FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001187 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001188
Jamie Madill33dc8432013-07-26 11:55:05 -04001189 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001190 {
1191 return NULL;
1192 }
1193 else
1194 {
1195 return fence->second;
1196 }
1197}
1198
1199Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1200{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001201 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001202
1203 if (query == mQueryMap.end())
1204 {
1205 return NULL;
1206 }
1207 else
1208 {
1209 if (!query->second && create)
1210 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001211 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001212 query->second->addRef();
1213 }
1214 return query->second;
1215 }
1216}
1217
Geoff Lang70d0f492015-12-10 17:45:46 -05001218Query *Context::getQuery(GLuint handle) const
1219{
1220 auto iter = mQueryMap.find(handle);
1221 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1222}
1223
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001224Texture *Context::getTargetTexture(GLenum target) const
1225{
Ian Ewellbda75592016-04-18 17:25:54 -04001226 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001227 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001228}
1229
Geoff Lang76b10c92014-09-05 16:28:14 -04001230Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001231{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001232 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233}
1234
Geoff Lang492a7e42014-11-05 13:27:06 -05001235Compiler *Context::getCompiler() const
1236{
1237 return mCompiler;
1238}
1239
Jamie Madill893ab082014-05-16 16:56:10 -04001240void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241{
1242 switch (pname)
1243 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001244 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001245 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001247 mGLState.getBooleanv(pname, params);
1248 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001249 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250}
1251
Jamie Madill893ab082014-05-16 16:56:10 -04001252void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001253{
Shannon Woods53a94a82014-06-24 15:20:36 -04001254 // Queries about context capabilities and maximums are answered by Context.
1255 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001256 switch (pname)
1257 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001258 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001259 params[0] = mCaps.minAliasedLineWidth;
1260 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001261 break;
1262 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001263 params[0] = mCaps.minAliasedPointSize;
1264 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001265 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001266 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001267 ASSERT(mExtensions.textureFilterAnisotropic);
1268 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001269 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001270 case GL_MAX_TEXTURE_LOD_BIAS:
1271 *params = mCaps.maxLODBias;
1272 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001273
1274 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1275 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1276 {
1277 ASSERT(mExtensions.pathRendering);
1278 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1279 memcpy(params, m, 16 * sizeof(GLfloat));
1280 }
1281 break;
1282
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001283 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001284 mGLState.getFloatv(pname, params);
1285 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001286 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001287}
1288
Jamie Madill893ab082014-05-16 16:56:10 -04001289void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001290{
Shannon Woods53a94a82014-06-24 15:20:36 -04001291 // Queries about context capabilities and maximums are answered by Context.
1292 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001293
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001294 switch (pname)
1295 {
Geoff Lang301d1612014-07-09 10:34:37 -04001296 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1297 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1298 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001299 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1300 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1301 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001302 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1303 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1304 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001305 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001306 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1307 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1308 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001309 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001310 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001311 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1312 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1313 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1314 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001315 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1316 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001317 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1318 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001319 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001320 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1321 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1322 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1323 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001324 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001325 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001326 break;
1327 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001328 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001329 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001330 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1331 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001332 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1333 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1334 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001335 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1336 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1337 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001338 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001339 case GL_MAX_VIEWPORT_DIMS:
1340 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001341 params[0] = mCaps.maxViewportWidth;
1342 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001343 }
1344 break;
1345 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001346 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001347 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001348 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1349 *params = mResetStrategy;
1350 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001351 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001352 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001353 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001354 case GL_SHADER_BINARY_FORMATS:
1355 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1356 break;
1357 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001358 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001359 break;
1360 case GL_PROGRAM_BINARY_FORMATS:
1361 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001362 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001363 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001364 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001365 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001366
1367 // GL_KHR_debug
1368 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1369 *params = mExtensions.maxDebugMessageLength;
1370 break;
1371 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1372 *params = mExtensions.maxDebugLoggedMessages;
1373 break;
1374 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1375 *params = mExtensions.maxDebugGroupStackDepth;
1376 break;
1377 case GL_MAX_LABEL_LENGTH:
1378 *params = mExtensions.maxLabelLength;
1379 break;
1380
Ian Ewell53f59f42016-01-28 17:36:55 -05001381 // GL_EXT_disjoint_timer_query
1382 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001383 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001384 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001385 case GL_MAX_FRAMEBUFFER_WIDTH:
1386 *params = mCaps.maxFramebufferWidth;
1387 break;
1388 case GL_MAX_FRAMEBUFFER_HEIGHT:
1389 *params = mCaps.maxFramebufferHeight;
1390 break;
1391 case GL_MAX_FRAMEBUFFER_SAMPLES:
1392 *params = mCaps.maxFramebufferSamples;
1393 break;
1394 case GL_MAX_SAMPLE_MASK_WORDS:
1395 *params = mCaps.maxSampleMaskWords;
1396 break;
1397 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1398 *params = mCaps.maxColorTextureSamples;
1399 break;
1400 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1401 *params = mCaps.maxDepthTextureSamples;
1402 break;
1403 case GL_MAX_INTEGER_SAMPLES:
1404 *params = mCaps.maxIntegerSamples;
1405 break;
1406 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1407 *params = mCaps.maxVertexAttribRelativeOffset;
1408 break;
1409 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1410 *params = mCaps.maxVertexAttribBindings;
1411 break;
1412 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1413 *params = mCaps.maxVertexAttribStride;
1414 break;
1415 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1416 *params = mCaps.maxVertexAtomicCounterBuffers;
1417 break;
1418 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1419 *params = mCaps.maxVertexAtomicCounters;
1420 break;
1421 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1422 *params = mCaps.maxVertexImageUniforms;
1423 break;
1424 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1425 *params = mCaps.maxVertexShaderStorageBlocks;
1426 break;
1427 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1428 *params = mCaps.maxFragmentAtomicCounterBuffers;
1429 break;
1430 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1431 *params = mCaps.maxFragmentAtomicCounters;
1432 break;
1433 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1434 *params = mCaps.maxFragmentImageUniforms;
1435 break;
1436 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1437 *params = mCaps.maxFragmentShaderStorageBlocks;
1438 break;
1439 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1440 *params = mCaps.minProgramTextureGatherOffset;
1441 break;
1442 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1443 *params = mCaps.maxProgramTextureGatherOffset;
1444 break;
1445 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1446 *params = mCaps.maxComputeWorkGroupInvocations;
1447 break;
1448 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1449 *params = mCaps.maxComputeUniformBlocks;
1450 break;
1451 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1452 *params = mCaps.maxComputeTextureImageUnits;
1453 break;
1454 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1455 *params = mCaps.maxComputeSharedMemorySize;
1456 break;
1457 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1458 *params = mCaps.maxComputeUniformComponents;
1459 break;
1460 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1461 *params = mCaps.maxComputeAtomicCounterBuffers;
1462 break;
1463 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1464 *params = mCaps.maxComputeAtomicCounters;
1465 break;
1466 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1467 *params = mCaps.maxComputeImageUniforms;
1468 break;
1469 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1470 *params = mCaps.maxCombinedComputeUniformComponents;
1471 break;
1472 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1473 *params = mCaps.maxComputeShaderStorageBlocks;
1474 break;
1475 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1476 *params = mCaps.maxCombinedShaderOutputResources;
1477 break;
1478 case GL_MAX_UNIFORM_LOCATIONS:
1479 *params = mCaps.maxUniformLocations;
1480 break;
1481 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1482 *params = mCaps.maxAtomicCounterBufferBindings;
1483 break;
1484 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1485 *params = mCaps.maxAtomicCounterBufferSize;
1486 break;
1487 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1488 *params = mCaps.maxCombinedAtomicCounterBuffers;
1489 break;
1490 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1491 *params = mCaps.maxCombinedAtomicCounters;
1492 break;
1493 case GL_MAX_IMAGE_UNITS:
1494 *params = mCaps.maxImageUnits;
1495 break;
1496 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1497 *params = mCaps.maxCombinedImageUniforms;
1498 break;
1499 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1500 *params = mCaps.maxShaderStorageBufferBindings;
1501 break;
1502 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1503 *params = mCaps.maxCombinedShaderStorageBlocks;
1504 break;
1505 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1506 *params = mCaps.shaderStorageBufferOffsetAlignment;
1507 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001508 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001509 mGLState.getIntegerv(mState, pname, params);
1510 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001511 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001512}
1513
Jamie Madill893ab082014-05-16 16:56:10 -04001514void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001515{
Shannon Woods53a94a82014-06-24 15:20:36 -04001516 // Queries about context capabilities and maximums are answered by Context.
1517 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001518 switch (pname)
1519 {
1520 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001521 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001522 break;
1523 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001524 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001525 break;
1526 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001527 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001528 break;
1529 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001530 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001531 break;
1532 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001533 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001534 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001535
1536 // GL_EXT_disjoint_timer_query
1537 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001538 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001539 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001540
1541 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1542 *params = mCaps.maxShaderStorageBlockSize;
1543 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001544 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001545 UNREACHABLE();
1546 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001547 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001548}
1549
Geoff Lang70d0f492015-12-10 17:45:46 -05001550void Context::getPointerv(GLenum pname, void **params) const
1551{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001552 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001553}
1554
Martin Radev66fb8202016-07-28 11:45:20 +03001555void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001556{
Shannon Woods53a94a82014-06-24 15:20:36 -04001557 // Queries about context capabilities and maximums are answered by Context.
1558 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001559
1560 GLenum nativeType;
1561 unsigned int numParams;
1562 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1563 ASSERT(queryStatus);
1564
1565 if (nativeType == GL_INT)
1566 {
1567 switch (target)
1568 {
1569 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1570 ASSERT(index < 3u);
1571 *data = mCaps.maxComputeWorkGroupCount[index];
1572 break;
1573 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1574 ASSERT(index < 3u);
1575 *data = mCaps.maxComputeWorkGroupSize[index];
1576 break;
1577 default:
1578 mGLState.getIntegeri_v(target, index, data);
1579 }
1580 }
1581 else
1582 {
1583 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1584 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001585}
1586
Martin Radev66fb8202016-07-28 11:45:20 +03001587void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001588{
Shannon Woods53a94a82014-06-24 15:20:36 -04001589 // Queries about context capabilities and maximums are answered by Context.
1590 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001591
1592 GLenum nativeType;
1593 unsigned int numParams;
1594 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1595 ASSERT(queryStatus);
1596
1597 if (nativeType == GL_INT_64_ANGLEX)
1598 {
1599 mGLState.getInteger64i_v(target, index, data);
1600 }
1601 else
1602 {
1603 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1604 }
1605}
1606
1607void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1608{
1609 // Queries about context capabilities and maximums are answered by Context.
1610 // Queries about current GL state values are answered by State.
1611
1612 GLenum nativeType;
1613 unsigned int numParams;
1614 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1615 ASSERT(queryStatus);
1616
1617 if (nativeType == GL_BOOL)
1618 {
1619 mGLState.getBooleani_v(target, index, data);
1620 }
1621 else
1622 {
1623 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1624 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001625}
1626
Jamie Madill675fe712016-12-19 13:07:54 -05001627void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001628{
Jamie Madill1b94d432015-08-07 13:23:23 -04001629 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001630 auto error = mImplementation->drawArrays(mode, first, count);
1631 handleError(error);
1632 if (!error.isError())
1633 {
1634 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1635 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001636}
1637
Jamie Madill675fe712016-12-19 13:07:54 -05001638void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001639{
1640 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001641 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1642 handleError(error);
1643 if (!error.isError())
1644 {
1645 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1646 }
Geoff Langf6db0982015-08-25 13:04:00 -04001647}
1648
Jamie Madill675fe712016-12-19 13:07:54 -05001649void Context::drawElements(GLenum mode,
1650 GLsizei count,
1651 GLenum type,
1652 const GLvoid *indices,
1653 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001654{
Jamie Madill1b94d432015-08-07 13:23:23 -04001655 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001656 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001657}
1658
Jamie Madill675fe712016-12-19 13:07:54 -05001659void Context::drawElementsInstanced(GLenum mode,
1660 GLsizei count,
1661 GLenum type,
1662 const GLvoid *indices,
1663 GLsizei instances,
1664 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001665{
1666 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001667 handleError(
1668 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001669}
1670
Jamie Madill675fe712016-12-19 13:07:54 -05001671void Context::drawRangeElements(GLenum mode,
1672 GLuint start,
1673 GLuint end,
1674 GLsizei count,
1675 GLenum type,
1676 const GLvoid *indices,
1677 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001678{
1679 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001680 handleError(
1681 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001682}
1683
Jiajia Qind9671222016-11-29 16:30:31 +08001684void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1685{
1686 syncRendererState();
1687 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1688}
1689
1690void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1691{
1692 syncRendererState();
1693 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1694}
1695
Jamie Madill675fe712016-12-19 13:07:54 -05001696void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001697{
Jamie Madill675fe712016-12-19 13:07:54 -05001698 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001699}
1700
Jamie Madill675fe712016-12-19 13:07:54 -05001701void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001702{
Jamie Madill675fe712016-12-19 13:07:54 -05001703 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001704}
1705
Austin Kinross6ee1e782015-05-29 17:05:37 -07001706void Context::insertEventMarker(GLsizei length, const char *marker)
1707{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001708 ASSERT(mImplementation);
1709 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001710}
1711
1712void Context::pushGroupMarker(GLsizei length, const char *marker)
1713{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001714 ASSERT(mImplementation);
1715 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001716}
1717
1718void Context::popGroupMarker()
1719{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001720 ASSERT(mImplementation);
1721 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001722}
1723
Geoff Langd8605522016-04-13 10:19:12 -04001724void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1725{
1726 Program *programObject = getProgram(program);
1727 ASSERT(programObject);
1728
1729 programObject->bindUniformLocation(location, name);
1730}
1731
Sami Väisänena797e062016-05-12 15:23:40 +03001732void Context::setCoverageModulation(GLenum components)
1733{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001734 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001735}
1736
Sami Väisänene45e53b2016-05-25 10:36:04 +03001737void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1738{
1739 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1740}
1741
1742void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1743{
1744 GLfloat I[16];
1745 angle::Matrix<GLfloat>::setToIdentity(I);
1746
1747 mGLState.loadPathRenderingMatrix(matrixMode, I);
1748}
1749
1750void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1751{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001752 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001753 if (!pathObj)
1754 return;
1755
1756 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1757 syncRendererState();
1758
1759 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1760}
1761
1762void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1763{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001764 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001765 if (!pathObj)
1766 return;
1767
1768 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1769 syncRendererState();
1770
1771 mImplementation->stencilStrokePath(pathObj, reference, mask);
1772}
1773
1774void Context::coverFillPath(GLuint path, GLenum coverMode)
1775{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001776 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001777 if (!pathObj)
1778 return;
1779
1780 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1781 syncRendererState();
1782
1783 mImplementation->coverFillPath(pathObj, coverMode);
1784}
1785
1786void Context::coverStrokePath(GLuint path, GLenum coverMode)
1787{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001788 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001789 if (!pathObj)
1790 return;
1791
1792 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1793 syncRendererState();
1794
1795 mImplementation->coverStrokePath(pathObj, coverMode);
1796}
1797
1798void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1799{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001800 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001801 if (!pathObj)
1802 return;
1803
1804 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1805 syncRendererState();
1806
1807 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1808}
1809
1810void Context::stencilThenCoverStrokePath(GLuint path,
1811 GLint reference,
1812 GLuint mask,
1813 GLenum coverMode)
1814{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001815 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001816 if (!pathObj)
1817 return;
1818
1819 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1820 syncRendererState();
1821
1822 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1823}
1824
Sami Väisänend59ca052016-06-21 16:10:00 +03001825void Context::coverFillPathInstanced(GLsizei numPaths,
1826 GLenum pathNameType,
1827 const void *paths,
1828 GLuint pathBase,
1829 GLenum coverMode,
1830 GLenum transformType,
1831 const GLfloat *transformValues)
1832{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001833 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001834
1835 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1836 syncRendererState();
1837
1838 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1839}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001840
Sami Väisänend59ca052016-06-21 16:10:00 +03001841void Context::coverStrokePathInstanced(GLsizei numPaths,
1842 GLenum pathNameType,
1843 const void *paths,
1844 GLuint pathBase,
1845 GLenum coverMode,
1846 GLenum transformType,
1847 const GLfloat *transformValues)
1848{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001849 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001850
1851 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1852 syncRendererState();
1853
1854 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1855 transformValues);
1856}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001857
Sami Väisänend59ca052016-06-21 16:10:00 +03001858void Context::stencilFillPathInstanced(GLsizei numPaths,
1859 GLenum pathNameType,
1860 const void *paths,
1861 GLuint pathBase,
1862 GLenum fillMode,
1863 GLuint mask,
1864 GLenum transformType,
1865 const GLfloat *transformValues)
1866{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001867 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001868
1869 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1870 syncRendererState();
1871
1872 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1873 transformValues);
1874}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001875
Sami Väisänend59ca052016-06-21 16:10:00 +03001876void Context::stencilStrokePathInstanced(GLsizei numPaths,
1877 GLenum pathNameType,
1878 const void *paths,
1879 GLuint pathBase,
1880 GLint reference,
1881 GLuint mask,
1882 GLenum transformType,
1883 const GLfloat *transformValues)
1884{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001885 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001886
1887 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1888 syncRendererState();
1889
1890 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1891 transformValues);
1892}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001893
Sami Väisänend59ca052016-06-21 16:10:00 +03001894void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1895 GLenum pathNameType,
1896 const void *paths,
1897 GLuint pathBase,
1898 GLenum fillMode,
1899 GLuint mask,
1900 GLenum coverMode,
1901 GLenum transformType,
1902 const GLfloat *transformValues)
1903{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001904 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001905
1906 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1907 syncRendererState();
1908
1909 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1910 transformType, transformValues);
1911}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001912
Sami Väisänend59ca052016-06-21 16:10:00 +03001913void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1914 GLenum pathNameType,
1915 const void *paths,
1916 GLuint pathBase,
1917 GLint reference,
1918 GLuint mask,
1919 GLenum coverMode,
1920 GLenum transformType,
1921 const GLfloat *transformValues)
1922{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001923 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001924
1925 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1926 syncRendererState();
1927
1928 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1929 transformType, transformValues);
1930}
1931
Sami Väisänen46eaa942016-06-29 10:26:37 +03001932void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1933{
1934 auto *programObject = getProgram(program);
1935
1936 programObject->bindFragmentInputLocation(location, name);
1937}
1938
1939void Context::programPathFragmentInputGen(GLuint program,
1940 GLint location,
1941 GLenum genMode,
1942 GLint components,
1943 const GLfloat *coeffs)
1944{
1945 auto *programObject = getProgram(program);
1946
1947 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1948}
1949
Jamie Madill437fa652016-05-03 15:13:24 -04001950void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001951{
Geoff Langda5777c2014-07-11 09:52:58 -04001952 if (error.isError())
1953 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001954 GLenum code = error.getCode();
1955 mErrors.insert(code);
1956 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1957 {
1958 markContextLost();
1959 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001960
1961 if (!error.getMessage().empty())
1962 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001963 auto *debug = &mGLState.getDebug();
1964 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1965 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001966 }
Geoff Langda5777c2014-07-11 09:52:58 -04001967 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001968}
1969
1970// Get one of the recorded errors and clear its flag, if any.
1971// [OpenGL ES 2.0.24] section 2.5 page 13.
1972GLenum Context::getError()
1973{
Geoff Langda5777c2014-07-11 09:52:58 -04001974 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001975 {
Geoff Langda5777c2014-07-11 09:52:58 -04001976 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001977 }
Geoff Langda5777c2014-07-11 09:52:58 -04001978 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001979 {
Geoff Langda5777c2014-07-11 09:52:58 -04001980 GLenum error = *mErrors.begin();
1981 mErrors.erase(mErrors.begin());
1982 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001983 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001984}
1985
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001986// NOTE: this function should not assume that this context is current!
1987void Context::markContextLost()
1988{
1989 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001990 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001991 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001992 mContextLostForced = true;
1993 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001994 mContextLost = true;
1995}
1996
1997bool Context::isContextLost()
1998{
1999 return mContextLost;
2000}
2001
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002002GLenum Context::getResetStatus()
2003{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002004 // Even if the application doesn't want to know about resets, we want to know
2005 // as it will allow us to skip all the calls.
2006 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002007 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002008 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002009 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002010 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002011 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002012
2013 // EXT_robustness, section 2.6: If the reset notification behavior is
2014 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2015 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2016 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002017 }
2018
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002019 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2020 // status should be returned at least once, and GL_NO_ERROR should be returned
2021 // once the device has finished resetting.
2022 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002023 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002024 ASSERT(mResetStatus == GL_NO_ERROR);
2025 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002026
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002027 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002028 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002029 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002030 }
2031 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002032 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002033 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002034 // If markContextLost was used to mark the context lost then
2035 // assume that is not recoverable, and continue to report the
2036 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002037 mResetStatus = mImplementation->getResetStatus();
2038 }
Jamie Madill893ab082014-05-16 16:56:10 -04002039
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002040 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002041}
2042
2043bool Context::isResetNotificationEnabled()
2044{
2045 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2046}
2047
Corentin Walleze3b10e82015-05-20 11:06:25 -04002048const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002049{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002050 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002051}
2052
2053EGLenum Context::getClientType() const
2054{
2055 return mClientType;
2056}
2057
2058EGLenum Context::getRenderBuffer() const
2059{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002060 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2061 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002062 {
2063 return EGL_NONE;
2064 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002065
2066 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2067 ASSERT(backAttachment != nullptr);
2068 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002069}
2070
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002071VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002072{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002073 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002074 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2075 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002076 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002077 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2078
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002079 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002080 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002081
2082 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002083}
2084
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002085TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002086{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002087 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002088 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2089 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002090 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002091 transformFeedback =
2092 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002093 transformFeedback->addRef();
2094 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002095 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002096
2097 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002098}
2099
2100bool Context::isVertexArrayGenerated(GLuint vertexArray)
2101{
Geoff Langf41a7152016-09-19 15:11:17 -04002102 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002103 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2104}
2105
2106bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2107{
Geoff Langf41a7152016-09-19 15:11:17 -04002108 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002109 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2110}
2111
Shannon Woods53a94a82014-06-24 15:20:36 -04002112void Context::detachTexture(GLuint texture)
2113{
2114 // Simple pass-through to State's detachTexture method, as textures do not require
2115 // allocation map management either here or in the resource manager at detach time.
2116 // Zero textures are held by the Context, and we don't attempt to request them from
2117 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002118 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002119}
2120
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002121void Context::detachBuffer(GLuint buffer)
2122{
Yuly Novikov5807a532015-12-03 13:01:22 -05002123 // Simple pass-through to State's detachBuffer method, since
2124 // only buffer attachments to container objects that are bound to the current context
2125 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002126
Yuly Novikov5807a532015-12-03 13:01:22 -05002127 // [OpenGL ES 3.2] section 5.1.2 page 45:
2128 // Attachments to unbound container objects, such as
2129 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2130 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002131 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002132}
2133
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002134void Context::detachFramebuffer(GLuint framebuffer)
2135{
Shannon Woods53a94a82014-06-24 15:20:36 -04002136 // Framebuffer detachment is handled by Context, because 0 is a valid
2137 // Framebuffer object, and a pointer to it must be passed from Context
2138 // to State at binding time.
2139
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002140 // [OpenGL ES 2.0.24] section 4.4 page 107:
2141 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2142 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2143
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002144 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002145 {
2146 bindReadFramebuffer(0);
2147 }
2148
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002149 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002150 {
2151 bindDrawFramebuffer(0);
2152 }
2153}
2154
2155void Context::detachRenderbuffer(GLuint renderbuffer)
2156{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002157 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002158}
2159
Jamie Madill57a89722013-07-02 11:57:03 -04002160void Context::detachVertexArray(GLuint vertexArray)
2161{
Jamie Madill77a72f62015-04-14 11:18:32 -04002162 // Vertex array detachment is handled by Context, because 0 is a valid
2163 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002164 // binding time.
2165
Jamie Madill57a89722013-07-02 11:57:03 -04002166 // [OpenGL ES 3.0.2] section 2.10 page 43:
2167 // If a vertex array object that is currently bound is deleted, the binding
2168 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002169 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002170 {
2171 bindVertexArray(0);
2172 }
2173}
2174
Geoff Langc8058452014-02-03 12:04:11 -05002175void Context::detachTransformFeedback(GLuint transformFeedback)
2176{
Corentin Walleza2257da2016-04-19 16:43:12 -04002177 // Transform feedback detachment is handled by Context, because 0 is a valid
2178 // transform feedback, and a pointer to it must be passed from Context to State at
2179 // binding time.
2180
2181 // The OpenGL specification doesn't mention what should happen when the currently bound
2182 // transform feedback object is deleted. Since it is a container object, we treat it like
2183 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002184 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002185 {
2186 bindTransformFeedback(0);
2187 }
Geoff Langc8058452014-02-03 12:04:11 -05002188}
2189
Jamie Madilldc356042013-07-19 16:36:57 -04002190void Context::detachSampler(GLuint sampler)
2191{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002192 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002193}
2194
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002195void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2196{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002197 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002198}
2199
Jamie Madille29d1672013-07-19 16:36:57 -04002200void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2201{
Geoff Langc1984ed2016-10-07 12:41:00 -04002202 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002203 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002204 SetSamplerParameteri(samplerObject, pname, param);
2205}
Jamie Madille29d1672013-07-19 16:36:57 -04002206
Geoff Langc1984ed2016-10-07 12:41:00 -04002207void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2208{
2209 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002210 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002211 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002212}
2213
2214void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2215{
Geoff Langc1984ed2016-10-07 12:41:00 -04002216 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002217 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002218 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002219}
2220
Geoff Langc1984ed2016-10-07 12:41:00 -04002221void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002222{
Geoff Langc1984ed2016-10-07 12:41:00 -04002223 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002224 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002225 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002226}
2227
Geoff Langc1984ed2016-10-07 12:41:00 -04002228void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002229{
Geoff Langc1984ed2016-10-07 12:41:00 -04002230 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002231 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002232 QuerySamplerParameteriv(samplerObject, pname, params);
2233}
Jamie Madill9675b802013-07-19 16:36:59 -04002234
Geoff Langc1984ed2016-10-07 12:41:00 -04002235void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2236{
2237 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002238 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002239 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002240}
2241
Olli Etuahof0fee072016-03-30 15:11:58 +03002242void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2243{
2244 gl::Program *programObject = getProgram(program);
2245 ASSERT(programObject != nullptr);
2246
2247 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2248 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2249}
2250
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002251void Context::initRendererString()
2252{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002253 std::ostringstream rendererString;
2254 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002255 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002256 rendererString << ")";
2257
Geoff Langcec35902014-04-16 10:52:36 -04002258 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002259}
2260
Geoff Langc339c4e2016-11-29 10:37:36 -05002261void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002262{
Geoff Langc339c4e2016-11-29 10:37:36 -05002263 const Version &clientVersion = getClientVersion();
2264
2265 std::ostringstream versionString;
2266 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2267 << ANGLE_VERSION_STRING << ")";
2268 mVersionString = MakeStaticString(versionString.str());
2269
2270 std::ostringstream shadingLanguageVersionString;
2271 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2272 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2273 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2274 << ")";
2275 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002276}
2277
Geoff Langcec35902014-04-16 10:52:36 -04002278void Context::initExtensionStrings()
2279{
Geoff Langc339c4e2016-11-29 10:37:36 -05002280 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2281 std::ostringstream combinedStringStream;
2282 std::copy(strings.begin(), strings.end(),
2283 std::ostream_iterator<const char *>(combinedStringStream, " "));
2284 return MakeStaticString(combinedStringStream.str());
2285 };
2286
2287 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002288 for (const auto &extensionString : mExtensions.getStrings())
2289 {
2290 mExtensionStrings.push_back(MakeStaticString(extensionString));
2291 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002292 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002293
Bryan Bernhart58806562017-01-05 13:09:31 -08002294 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2295
Geoff Langc339c4e2016-11-29 10:37:36 -05002296 mRequestableExtensionStrings.clear();
2297 for (const auto &extensionInfo : GetExtensionInfoMap())
2298 {
2299 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002300 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2301 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002302 {
2303 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2304 }
2305 }
2306 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002307}
2308
Geoff Langc339c4e2016-11-29 10:37:36 -05002309const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002310{
Geoff Langc339c4e2016-11-29 10:37:36 -05002311 switch (name)
2312 {
2313 case GL_VENDOR:
2314 return reinterpret_cast<const GLubyte *>("Google Inc.");
2315
2316 case GL_RENDERER:
2317 return reinterpret_cast<const GLubyte *>(mRendererString);
2318
2319 case GL_VERSION:
2320 return reinterpret_cast<const GLubyte *>(mVersionString);
2321
2322 case GL_SHADING_LANGUAGE_VERSION:
2323 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2324
2325 case GL_EXTENSIONS:
2326 return reinterpret_cast<const GLubyte *>(mExtensionString);
2327
2328 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2329 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2330
2331 default:
2332 UNREACHABLE();
2333 return nullptr;
2334 }
Geoff Langcec35902014-04-16 10:52:36 -04002335}
2336
Geoff Langc339c4e2016-11-29 10:37:36 -05002337const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002338{
Geoff Langc339c4e2016-11-29 10:37:36 -05002339 switch (name)
2340 {
2341 case GL_EXTENSIONS:
2342 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2343
2344 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2345 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2346
2347 default:
2348 UNREACHABLE();
2349 return nullptr;
2350 }
Geoff Langcec35902014-04-16 10:52:36 -04002351}
2352
2353size_t Context::getExtensionStringCount() const
2354{
2355 return mExtensionStrings.size();
2356}
2357
Geoff Langc339c4e2016-11-29 10:37:36 -05002358void Context::requestExtension(const char *name)
2359{
2360 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2361 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2362 const auto &extension = extensionInfos.at(name);
2363 ASSERT(extension.Requestable);
2364
2365 if (mExtensions.*(extension.ExtensionsMember))
2366 {
2367 // Extension already enabled
2368 return;
2369 }
2370
2371 mExtensions.*(extension.ExtensionsMember) = true;
2372 updateCaps();
2373 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002374
2375 // Re-create the compiler with the requested extensions enabled.
2376 SafeDelete(mCompiler);
2377 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002378}
2379
2380size_t Context::getRequestableExtensionStringCount() const
2381{
2382 return mRequestableExtensionStrings.size();
2383}
2384
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002385void Context::beginTransformFeedback(GLenum primitiveMode)
2386{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002387 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002388 ASSERT(transformFeedback != nullptr);
2389 ASSERT(!transformFeedback->isPaused());
2390
Jamie Madill6c1f6712017-02-14 19:08:04 -05002391 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002392}
2393
2394bool Context::hasActiveTransformFeedback(GLuint program) const
2395{
2396 for (auto pair : mTransformFeedbackMap)
2397 {
2398 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2399 {
2400 return true;
2401 }
2402 }
2403 return false;
2404}
2405
Corentin Wallezc295e512017-01-27 17:47:50 -05002406void Context::initCaps(bool webGLContext, const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002407{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002408 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002409
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002410 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002411
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002412 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002413
Geoff Langeb66a6e2016-10-31 13:06:12 -04002414 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002415 {
2416 // Disable ES3+ extensions
2417 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002418 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002419 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002420 }
2421
Geoff Langeb66a6e2016-10-31 13:06:12 -04002422 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002423 {
2424 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2425 //mExtensions.sRGB = false;
2426 }
2427
Jamie Madill00ed7a12016-05-19 13:13:38 -04002428 // Some extensions are always available because they are implemented in the GL layer.
2429 mExtensions.bindUniformLocation = true;
2430 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002431 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002432 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002433
2434 // Enable the no error extension if the context was created with the flag.
2435 mExtensions.noError = mSkipValidation;
2436
Corentin Wallezccab69d2017-01-27 16:57:15 -05002437 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002438 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002439
Geoff Lang70d0f492015-12-10 17:45:46 -05002440 // Explicitly enable GL_KHR_debug
2441 mExtensions.debug = true;
2442 mExtensions.maxDebugMessageLength = 1024;
2443 mExtensions.maxDebugLoggedMessages = 1024;
2444 mExtensions.maxDebugGroupStackDepth = 1024;
2445 mExtensions.maxLabelLength = 1024;
2446
Geoff Langff5b2d52016-09-07 11:32:23 -04002447 // Explicitly enable GL_ANGLE_robust_client_memory
2448 mExtensions.robustClientMemory = true;
2449
Geoff Lang301d1612014-07-09 10:34:37 -04002450 // Apply implementation limits
2451 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002452 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2453 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2454
2455 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002456
Geoff Langc287ea62016-09-16 14:46:51 -04002457 // WebGL compatibility
2458 mExtensions.webglCompatibility = webGLContext;
2459 for (const auto &extensionInfo : GetExtensionInfoMap())
2460 {
2461 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002462 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002463 {
2464 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2465 }
2466 }
2467
2468 // Generate texture caps
2469 updateCaps();
2470}
2471
2472void Context::updateCaps()
2473{
Geoff Lang900013c2014-07-07 11:32:19 -04002474 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002475 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002476
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002477 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002478 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2479 {
2480 GLenum format = i->first;
2481 TextureCaps formatCaps = i->second;
2482
Geoff Lang5d601382014-07-22 15:14:06 -04002483 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002484
Geoff Lang0d8b7242015-09-09 14:56:53 -04002485 // Update the format caps based on the client version and extensions.
2486 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2487 // ES3.
2488 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002489 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002490 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002491 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002492 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002493 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002494
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002495 // OpenGL ES does not support multisampling with non-rendererable formats
2496 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2497 if (!formatInfo.renderSupport ||
2498 (getClientVersion() < ES_3_1 &&
2499 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002500 {
Geoff Langd87878e2014-09-19 15:42:59 -04002501 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002502 }
Geoff Langd87878e2014-09-19 15:42:59 -04002503
2504 if (formatCaps.texturable && formatInfo.compressed)
2505 {
2506 mCaps.compressedTextureFormats.push_back(format);
2507 }
2508
2509 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002510 }
2511}
2512
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002513void Context::initWorkarounds()
2514{
2515 // Lose the context upon out of memory error if the application is
2516 // expecting to watch for those events.
2517 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2518}
2519
Jamie Madill1b94d432015-08-07 13:23:23 -04002520void Context::syncRendererState()
2521{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002522 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2523 mImplementation->syncState(mGLState, dirtyBits);
2524 mGLState.clearDirtyBits();
2525 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002526}
2527
Jamie Madillad9f24e2016-02-12 09:27:24 -05002528void Context::syncRendererState(const State::DirtyBits &bitMask,
2529 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002530{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002531 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2532 mImplementation->syncState(mGLState, dirtyBits);
2533 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002534
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002535 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002536}
Jamie Madillc29968b2016-01-20 11:17:23 -05002537
2538void Context::blitFramebuffer(GLint srcX0,
2539 GLint srcY0,
2540 GLint srcX1,
2541 GLint srcY1,
2542 GLint dstX0,
2543 GLint dstY0,
2544 GLint dstX1,
2545 GLint dstY1,
2546 GLbitfield mask,
2547 GLenum filter)
2548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002549 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002550 ASSERT(drawFramebuffer);
2551
2552 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2553 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2554
Jamie Madillad9f24e2016-02-12 09:27:24 -05002555 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002556
Jamie Madill8415b5f2016-04-26 13:41:39 -04002557 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002558}
Jamie Madillc29968b2016-01-20 11:17:23 -05002559
2560void Context::clear(GLbitfield mask)
2561{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002562 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002563 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002564}
2565
2566void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2567{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002568 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002569 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2570 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002571}
2572
2573void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2574{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002575 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002576 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2577 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002578}
2579
2580void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2581{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002582 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002583 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2584 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002585}
2586
2587void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2588{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002589 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002590 ASSERT(framebufferObject);
2591
2592 // If a buffer is not present, the clear has no effect
2593 if (framebufferObject->getDepthbuffer() == nullptr &&
2594 framebufferObject->getStencilbuffer() == nullptr)
2595 {
2596 return;
2597 }
2598
Jamie Madillad9f24e2016-02-12 09:27:24 -05002599 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002600 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2601 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002602}
2603
2604void Context::readPixels(GLint x,
2605 GLint y,
2606 GLsizei width,
2607 GLsizei height,
2608 GLenum format,
2609 GLenum type,
2610 GLvoid *pixels)
2611{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002612 if (width == 0 || height == 0)
2613 {
2614 return;
2615 }
2616
Jamie Madillad9f24e2016-02-12 09:27:24 -05002617 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002618
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002619 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002620 ASSERT(framebufferObject);
2621
2622 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002623 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002624}
2625
2626void Context::copyTexImage2D(GLenum target,
2627 GLint level,
2628 GLenum internalformat,
2629 GLint x,
2630 GLint y,
2631 GLsizei width,
2632 GLsizei height,
2633 GLint border)
2634{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002635 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002636 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002637
Jamie Madillc29968b2016-01-20 11:17:23 -05002638 Rectangle sourceArea(x, y, width, height);
2639
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002640 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002641 Texture *texture =
2642 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002643 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002644}
2645
2646void Context::copyTexSubImage2D(GLenum target,
2647 GLint level,
2648 GLint xoffset,
2649 GLint yoffset,
2650 GLint x,
2651 GLint y,
2652 GLsizei width,
2653 GLsizei height)
2654{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002655 if (width == 0 || height == 0)
2656 {
2657 return;
2658 }
2659
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002660 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002661 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002662
Jamie Madillc29968b2016-01-20 11:17:23 -05002663 Offset destOffset(xoffset, yoffset, 0);
2664 Rectangle sourceArea(x, y, width, height);
2665
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002666 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002667 Texture *texture =
2668 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002669 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002670}
2671
2672void Context::copyTexSubImage3D(GLenum target,
2673 GLint level,
2674 GLint xoffset,
2675 GLint yoffset,
2676 GLint zoffset,
2677 GLint x,
2678 GLint y,
2679 GLsizei width,
2680 GLsizei height)
2681{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002682 if (width == 0 || height == 0)
2683 {
2684 return;
2685 }
2686
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002687 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002688 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002689
Jamie Madillc29968b2016-01-20 11:17:23 -05002690 Offset destOffset(xoffset, yoffset, zoffset);
2691 Rectangle sourceArea(x, y, width, height);
2692
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002693 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002694 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002695 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002696}
2697
2698void Context::framebufferTexture2D(GLenum target,
2699 GLenum attachment,
2700 GLenum textarget,
2701 GLuint texture,
2702 GLint level)
2703{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002704 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002705 ASSERT(framebuffer);
2706
2707 if (texture != 0)
2708 {
2709 Texture *textureObj = getTexture(texture);
2710
2711 ImageIndex index = ImageIndex::MakeInvalid();
2712
2713 if (textarget == GL_TEXTURE_2D)
2714 {
2715 index = ImageIndex::Make2D(level);
2716 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002717 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2718 {
2719 ASSERT(level == 0);
2720 index = ImageIndex::Make2DMultisample();
2721 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002722 else
2723 {
2724 ASSERT(IsCubeMapTextureTarget(textarget));
2725 index = ImageIndex::MakeCube(textarget, level);
2726 }
2727
2728 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2729 }
2730 else
2731 {
2732 framebuffer->resetAttachment(attachment);
2733 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002734
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002735 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002736}
2737
2738void Context::framebufferRenderbuffer(GLenum target,
2739 GLenum attachment,
2740 GLenum renderbuffertarget,
2741 GLuint renderbuffer)
2742{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002743 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002744 ASSERT(framebuffer);
2745
2746 if (renderbuffer != 0)
2747 {
2748 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2749 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2750 renderbufferObject);
2751 }
2752 else
2753 {
2754 framebuffer->resetAttachment(attachment);
2755 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002756
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002757 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002758}
2759
2760void Context::framebufferTextureLayer(GLenum target,
2761 GLenum attachment,
2762 GLuint texture,
2763 GLint level,
2764 GLint layer)
2765{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002766 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002767 ASSERT(framebuffer);
2768
2769 if (texture != 0)
2770 {
2771 Texture *textureObject = getTexture(texture);
2772
2773 ImageIndex index = ImageIndex::MakeInvalid();
2774
2775 if (textureObject->getTarget() == GL_TEXTURE_3D)
2776 {
2777 index = ImageIndex::Make3D(level, layer);
2778 }
2779 else
2780 {
2781 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2782 index = ImageIndex::Make2DArray(level, layer);
2783 }
2784
2785 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2786 }
2787 else
2788 {
2789 framebuffer->resetAttachment(attachment);
2790 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002791
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002792 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002793}
2794
2795void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2796{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002797 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002798 ASSERT(framebuffer);
2799 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002800 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002801}
2802
2803void Context::readBuffer(GLenum mode)
2804{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002805 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002806 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002807 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002808}
2809
2810void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2811{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002812 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002813 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002814
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002815 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002816 ASSERT(framebuffer);
2817
2818 // The specification isn't clear what should be done when the framebuffer isn't complete.
2819 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002820 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002821}
2822
2823void Context::invalidateFramebuffer(GLenum target,
2824 GLsizei numAttachments,
2825 const GLenum *attachments)
2826{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002827 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002828 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002829
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002830 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002831 ASSERT(framebuffer);
2832
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002833 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002834 {
Jamie Madill437fa652016-05-03 15:13:24 -04002835 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002836 }
Jamie Madill437fa652016-05-03 15:13:24 -04002837
2838 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002839}
2840
2841void Context::invalidateSubFramebuffer(GLenum target,
2842 GLsizei numAttachments,
2843 const GLenum *attachments,
2844 GLint x,
2845 GLint y,
2846 GLsizei width,
2847 GLsizei height)
2848{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002849 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002850 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002851
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002852 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002853 ASSERT(framebuffer);
2854
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002855 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002856 {
Jamie Madill437fa652016-05-03 15:13:24 -04002857 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002858 }
Jamie Madill437fa652016-05-03 15:13:24 -04002859
2860 Rectangle area(x, y, width, height);
2861 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002862}
2863
Jamie Madill73a84962016-02-12 09:27:23 -05002864void Context::texImage2D(GLenum target,
2865 GLint level,
2866 GLint internalformat,
2867 GLsizei width,
2868 GLsizei height,
2869 GLint border,
2870 GLenum format,
2871 GLenum type,
2872 const GLvoid *pixels)
2873{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002874 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002875
2876 Extents size(width, height, 1);
2877 Texture *texture =
2878 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002879 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2880 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002881}
2882
2883void Context::texImage3D(GLenum target,
2884 GLint level,
2885 GLint internalformat,
2886 GLsizei width,
2887 GLsizei height,
2888 GLsizei depth,
2889 GLint border,
2890 GLenum format,
2891 GLenum type,
2892 const GLvoid *pixels)
2893{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002894 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002895
2896 Extents size(width, height, depth);
2897 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002898 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2899 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002900}
2901
2902void Context::texSubImage2D(GLenum target,
2903 GLint level,
2904 GLint xoffset,
2905 GLint yoffset,
2906 GLsizei width,
2907 GLsizei height,
2908 GLenum format,
2909 GLenum type,
2910 const GLvoid *pixels)
2911{
2912 // Zero sized uploads are valid but no-ops
2913 if (width == 0 || height == 0)
2914 {
2915 return;
2916 }
2917
Jamie Madillad9f24e2016-02-12 09:27:24 -05002918 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002919
2920 Box area(xoffset, yoffset, 0, width, height, 1);
2921 Texture *texture =
2922 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002923 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2924 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002925}
2926
2927void Context::texSubImage3D(GLenum target,
2928 GLint level,
2929 GLint xoffset,
2930 GLint yoffset,
2931 GLint zoffset,
2932 GLsizei width,
2933 GLsizei height,
2934 GLsizei depth,
2935 GLenum format,
2936 GLenum type,
2937 const GLvoid *pixels)
2938{
2939 // Zero sized uploads are valid but no-ops
2940 if (width == 0 || height == 0 || depth == 0)
2941 {
2942 return;
2943 }
2944
Jamie Madillad9f24e2016-02-12 09:27:24 -05002945 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002946
2947 Box area(xoffset, yoffset, zoffset, width, height, depth);
2948 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002949 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2950 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002951}
2952
2953void Context::compressedTexImage2D(GLenum target,
2954 GLint level,
2955 GLenum internalformat,
2956 GLsizei width,
2957 GLsizei height,
2958 GLint border,
2959 GLsizei imageSize,
2960 const GLvoid *data)
2961{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002962 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002963
2964 Extents size(width, height, 1);
2965 Texture *texture =
2966 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002967 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002968 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002969 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002970}
2971
2972void Context::compressedTexImage3D(GLenum target,
2973 GLint level,
2974 GLenum internalformat,
2975 GLsizei width,
2976 GLsizei height,
2977 GLsizei depth,
2978 GLint border,
2979 GLsizei imageSize,
2980 const GLvoid *data)
2981{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002982 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002983
2984 Extents size(width, height, depth);
2985 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002986 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002987 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002988 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002989}
2990
2991void Context::compressedTexSubImage2D(GLenum target,
2992 GLint level,
2993 GLint xoffset,
2994 GLint yoffset,
2995 GLsizei width,
2996 GLsizei height,
2997 GLenum format,
2998 GLsizei imageSize,
2999 const GLvoid *data)
3000{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003001 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003002
3003 Box area(xoffset, yoffset, 0, width, height, 1);
3004 Texture *texture =
3005 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003006 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003007 format, imageSize,
3008 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003009}
3010
3011void Context::compressedTexSubImage3D(GLenum target,
3012 GLint level,
3013 GLint xoffset,
3014 GLint yoffset,
3015 GLint zoffset,
3016 GLsizei width,
3017 GLsizei height,
3018 GLsizei depth,
3019 GLenum format,
3020 GLsizei imageSize,
3021 const GLvoid *data)
3022{
3023 // Zero sized uploads are valid but no-ops
3024 if (width == 0 || height == 0)
3025 {
3026 return;
3027 }
3028
Jamie Madillad9f24e2016-02-12 09:27:24 -05003029 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003030
3031 Box area(xoffset, yoffset, zoffset, width, height, depth);
3032 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003033 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003034 format, imageSize,
3035 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003036}
3037
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003038void Context::generateMipmap(GLenum target)
3039{
3040 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003041 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003042}
3043
Geoff Lang97073d12016-04-20 10:42:34 -07003044void Context::copyTextureCHROMIUM(GLuint sourceId,
3045 GLuint destId,
3046 GLint internalFormat,
3047 GLenum destType,
3048 GLboolean unpackFlipY,
3049 GLboolean unpackPremultiplyAlpha,
3050 GLboolean unpackUnmultiplyAlpha)
3051{
3052 syncStateForTexImage();
3053
3054 gl::Texture *sourceTexture = getTexture(sourceId);
3055 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003056 handleError(destTexture->copyTexture(this, internalFormat, destType, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003057 unpackPremultiplyAlpha == GL_TRUE,
3058 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3059}
3060
3061void Context::copySubTextureCHROMIUM(GLuint sourceId,
3062 GLuint destId,
3063 GLint xoffset,
3064 GLint yoffset,
3065 GLint x,
3066 GLint y,
3067 GLsizei width,
3068 GLsizei height,
3069 GLboolean unpackFlipY,
3070 GLboolean unpackPremultiplyAlpha,
3071 GLboolean unpackUnmultiplyAlpha)
3072{
3073 // Zero sized copies are valid but no-ops
3074 if (width == 0 || height == 0)
3075 {
3076 return;
3077 }
3078
3079 syncStateForTexImage();
3080
3081 gl::Texture *sourceTexture = getTexture(sourceId);
3082 gl::Texture *destTexture = getTexture(destId);
3083 Offset offset(xoffset, yoffset, 0);
3084 Rectangle area(x, y, width, height);
Jamie Madill8897afa2017-02-06 17:17:23 -05003085 handleError(destTexture->copySubTexture(this, offset, area, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003086 unpackPremultiplyAlpha == GL_TRUE,
3087 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3088}
3089
Geoff Lang47110bf2016-04-20 11:13:22 -07003090void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3091{
3092 syncStateForTexImage();
3093
3094 gl::Texture *sourceTexture = getTexture(sourceId);
3095 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003096 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003097}
3098
Geoff Lang496c02d2016-10-20 11:38:11 -07003099void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003100{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003101 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003102 ASSERT(buffer);
3103
Geoff Lang496c02d2016-10-20 11:38:11 -07003104 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003105}
3106
3107GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3108{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003109 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003110 ASSERT(buffer);
3111
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003112 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003113 if (error.isError())
3114 {
Jamie Madill437fa652016-05-03 15:13:24 -04003115 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003116 return nullptr;
3117 }
3118
3119 return buffer->getMapPointer();
3120}
3121
3122GLboolean Context::unmapBuffer(GLenum target)
3123{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003124 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003125 ASSERT(buffer);
3126
3127 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003128 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003129 if (error.isError())
3130 {
Jamie Madill437fa652016-05-03 15:13:24 -04003131 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003132 return GL_FALSE;
3133 }
3134
3135 return result;
3136}
3137
3138GLvoid *Context::mapBufferRange(GLenum target,
3139 GLintptr offset,
3140 GLsizeiptr length,
3141 GLbitfield access)
3142{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003143 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003144 ASSERT(buffer);
3145
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003146 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003147 if (error.isError())
3148 {
Jamie Madill437fa652016-05-03 15:13:24 -04003149 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003150 return nullptr;
3151 }
3152
3153 return buffer->getMapPointer();
3154}
3155
3156void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3157{
3158 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3159}
3160
Jamie Madillad9f24e2016-02-12 09:27:24 -05003161void Context::syncStateForReadPixels()
3162{
3163 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3164}
3165
3166void Context::syncStateForTexImage()
3167{
3168 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3169}
3170
3171void Context::syncStateForClear()
3172{
3173 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3174}
3175
3176void Context::syncStateForBlit()
3177{
3178 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3179}
3180
Jamie Madillc20ab272016-06-09 07:20:46 -07003181void Context::activeTexture(GLenum texture)
3182{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003183 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003184}
3185
3186void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3187{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003188 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003189}
3190
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003191void Context::blendEquation(GLenum mode)
3192{
3193 mGLState.setBlendEquation(mode, mode);
3194}
3195
Jamie Madillc20ab272016-06-09 07:20:46 -07003196void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3197{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003198 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003199}
3200
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003201void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3202{
3203 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3204}
3205
Jamie Madillc20ab272016-06-09 07:20:46 -07003206void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3207{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003208 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003209}
3210
3211void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3212{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003213 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003214}
3215
3216void Context::clearDepthf(GLclampf depth)
3217{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003218 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003219}
3220
3221void Context::clearStencil(GLint s)
3222{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003223 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003224}
3225
3226void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3227{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003228 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003229}
3230
3231void Context::cullFace(GLenum mode)
3232{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003233 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003234}
3235
3236void Context::depthFunc(GLenum func)
3237{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003238 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003239}
3240
3241void Context::depthMask(GLboolean flag)
3242{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003243 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003244}
3245
3246void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3247{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003248 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003249}
3250
3251void Context::disable(GLenum cap)
3252{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003253 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003254}
3255
3256void Context::disableVertexAttribArray(GLuint index)
3257{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003258 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003259}
3260
3261void Context::enable(GLenum cap)
3262{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003263 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003264}
3265
3266void Context::enableVertexAttribArray(GLuint index)
3267{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003268 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003269}
3270
3271void Context::frontFace(GLenum mode)
3272{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003273 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003274}
3275
3276void Context::hint(GLenum target, GLenum mode)
3277{
3278 switch (target)
3279 {
3280 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003281 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003282 break;
3283
3284 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003285 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003286 break;
3287
3288 default:
3289 UNREACHABLE();
3290 return;
3291 }
3292}
3293
3294void Context::lineWidth(GLfloat width)
3295{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003297}
3298
3299void Context::pixelStorei(GLenum pname, GLint param)
3300{
3301 switch (pname)
3302 {
3303 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003304 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003305 break;
3306
3307 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003308 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003309 break;
3310
3311 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003312 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003313 break;
3314
3315 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003316 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003317 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003318 break;
3319
3320 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003321 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003322 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003323 break;
3324
3325 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003326 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003327 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003328 break;
3329
3330 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003331 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003332 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003333 break;
3334
3335 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003336 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003337 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003338 break;
3339
3340 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003341 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003342 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003343 break;
3344
3345 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003346 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003347 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003348 break;
3349
3350 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003351 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003352 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003353 break;
3354
3355 default:
3356 UNREACHABLE();
3357 return;
3358 }
3359}
3360
3361void Context::polygonOffset(GLfloat factor, GLfloat units)
3362{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003363 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003364}
3365
3366void Context::sampleCoverage(GLclampf value, GLboolean invert)
3367{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003368 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003369}
3370
3371void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3372{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003373 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003374}
3375
3376void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3377{
3378 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3379 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003380 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003381 }
3382
3383 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3384 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003385 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003386 }
3387}
3388
3389void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3390{
3391 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3392 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003393 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003394 }
3395
3396 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3397 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003398 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003399 }
3400}
3401
3402void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3403{
3404 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3405 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003406 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003407 }
3408
3409 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3410 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003411 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003412 }
3413}
3414
3415void Context::vertexAttrib1f(GLuint index, GLfloat x)
3416{
3417 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003418 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003419}
3420
3421void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3422{
3423 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425}
3426
3427void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3428{
3429 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003430 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003431}
3432
3433void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3434{
3435 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003436 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003437}
3438
3439void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3440{
3441 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003442 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003443}
3444
3445void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3446{
3447 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003448 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003449}
3450
3451void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3452{
3453 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003454 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003455}
3456
3457void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3458{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003460}
3461
3462void Context::vertexAttribPointer(GLuint index,
3463 GLint size,
3464 GLenum type,
3465 GLboolean normalized,
3466 GLsizei stride,
3467 const GLvoid *ptr)
3468{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003469 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3470 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003471}
3472
3473void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3474{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003475 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003476}
3477
3478void Context::vertexAttribIPointer(GLuint index,
3479 GLint size,
3480 GLenum type,
3481 GLsizei stride,
3482 const GLvoid *pointer)
3483{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003484 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3485 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003486}
3487
3488void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3489{
3490 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003491 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003492}
3493
3494void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3495{
3496 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003497 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003498}
3499
3500void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3501{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003502 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003503}
3504
3505void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3506{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003507 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003508}
3509
3510void Context::debugMessageControl(GLenum source,
3511 GLenum type,
3512 GLenum severity,
3513 GLsizei count,
3514 const GLuint *ids,
3515 GLboolean enabled)
3516{
3517 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003518 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3519 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003520}
3521
3522void Context::debugMessageInsert(GLenum source,
3523 GLenum type,
3524 GLuint id,
3525 GLenum severity,
3526 GLsizei length,
3527 const GLchar *buf)
3528{
3529 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003530 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003531}
3532
3533void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003535 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003536}
3537
3538GLuint Context::getDebugMessageLog(GLuint count,
3539 GLsizei bufSize,
3540 GLenum *sources,
3541 GLenum *types,
3542 GLuint *ids,
3543 GLenum *severities,
3544 GLsizei *lengths,
3545 GLchar *messageLog)
3546{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003547 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3548 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003549}
3550
3551void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3552{
3553 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003554 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003555}
3556
3557void Context::popDebugGroup()
3558{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003559 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003560}
3561
Jamie Madill29639852016-09-02 15:00:09 -04003562void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3563{
3564 Buffer *buffer = mGLState.getTargetBuffer(target);
3565 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003566 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003567}
3568
3569void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3570{
3571 if (data == nullptr)
3572 {
3573 return;
3574 }
3575
3576 Buffer *buffer = mGLState.getTargetBuffer(target);
3577 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003578 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003579}
3580
Jamie Madillef300b12016-10-07 15:12:09 -04003581void Context::attachShader(GLuint program, GLuint shader)
3582{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003583 auto programObject = mState.mShaderPrograms->getProgram(program);
3584 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003585 ASSERT(programObject && shaderObject);
3586 programObject->attachShader(shaderObject);
3587}
3588
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003589const Workarounds &Context::getWorkarounds() const
3590{
3591 return mWorkarounds;
3592}
3593
Jamie Madillb0817d12016-11-01 15:48:31 -04003594void Context::copyBufferSubData(GLenum readTarget,
3595 GLenum writeTarget,
3596 GLintptr readOffset,
3597 GLintptr writeOffset,
3598 GLsizeiptr size)
3599{
3600 // if size is zero, the copy is a successful no-op
3601 if (size == 0)
3602 {
3603 return;
3604 }
3605
3606 // TODO(jmadill): cache these.
3607 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3608 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3609
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003610 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003611}
3612
Jamie Madill01a80ee2016-11-07 12:06:18 -05003613void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3614{
3615 Program *programObject = getProgram(program);
3616 // TODO(jmadill): Re-use this from the validation if possible.
3617 ASSERT(programObject);
3618 programObject->bindAttributeLocation(index, name);
3619}
3620
3621void Context::bindBuffer(GLenum target, GLuint buffer)
3622{
3623 switch (target)
3624 {
3625 case GL_ARRAY_BUFFER:
3626 bindArrayBuffer(buffer);
3627 break;
3628 case GL_ELEMENT_ARRAY_BUFFER:
3629 bindElementArrayBuffer(buffer);
3630 break;
3631 case GL_COPY_READ_BUFFER:
3632 bindCopyReadBuffer(buffer);
3633 break;
3634 case GL_COPY_WRITE_BUFFER:
3635 bindCopyWriteBuffer(buffer);
3636 break;
3637 case GL_PIXEL_PACK_BUFFER:
3638 bindPixelPackBuffer(buffer);
3639 break;
3640 case GL_PIXEL_UNPACK_BUFFER:
3641 bindPixelUnpackBuffer(buffer);
3642 break;
3643 case GL_UNIFORM_BUFFER:
3644 bindGenericUniformBuffer(buffer);
3645 break;
3646 case GL_TRANSFORM_FEEDBACK_BUFFER:
3647 bindGenericTransformFeedbackBuffer(buffer);
3648 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003649 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003650 if (buffer != 0)
3651 {
3652 // Binding buffers to this binding point is not implemented yet.
3653 UNIMPLEMENTED();
3654 }
Geoff Lang3b573612016-10-31 14:08:10 -04003655 break;
3656 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003657 if (buffer != 0)
3658 {
3659 // Binding buffers to this binding point is not implemented yet.
3660 UNIMPLEMENTED();
3661 }
Geoff Lang3b573612016-10-31 14:08:10 -04003662 break;
3663 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003664 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003665 break;
3666 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003667 if (buffer != 0)
3668 {
3669 // Binding buffers to this binding point is not implemented yet.
3670 UNIMPLEMENTED();
3671 }
Geoff Lang3b573612016-10-31 14:08:10 -04003672 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003673
3674 default:
3675 UNREACHABLE();
3676 break;
3677 }
3678}
3679
3680void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3681{
3682 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3683 {
3684 bindReadFramebuffer(framebuffer);
3685 }
3686
3687 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3688 {
3689 bindDrawFramebuffer(framebuffer);
3690 }
3691}
3692
3693void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3694{
3695 ASSERT(target == GL_RENDERBUFFER);
3696 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003697 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003698 mGLState.setRenderbufferBinding(object);
3699}
3700
JiangYizhoubddc46b2016-12-09 09:50:51 +08003701void Context::texStorage2DMultisample(GLenum target,
3702 GLsizei samples,
3703 GLenum internalformat,
3704 GLsizei width,
3705 GLsizei height,
3706 GLboolean fixedsamplelocations)
3707{
3708 Extents size(width, height, 1);
3709 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003710 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003711 fixedsamplelocations));
3712}
3713
3714void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3715{
3716 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3717 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3718
3719 switch (pname)
3720 {
3721 case GL_SAMPLE_POSITION:
3722 handleError(framebuffer->getSamplePosition(index, val));
3723 break;
3724 default:
3725 UNREACHABLE();
3726 }
3727}
3728
Jamie Madille8fb6402017-02-14 17:56:40 -05003729void Context::renderbufferStorage(GLenum target,
3730 GLenum internalformat,
3731 GLsizei width,
3732 GLsizei height)
3733{
3734 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
3735 handleError(renderbuffer->setStorage(internalformat, width, height));
3736}
3737
3738void Context::renderbufferStorageMultisample(GLenum target,
3739 GLsizei samples,
3740 GLenum internalformat,
3741 GLsizei width,
3742 GLsizei height)
3743{
3744
3745 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
3746 handleError(renderbuffer->setStorageMultisample(samples, internalformat, width, height));
3747}
3748
Jamie Madillc29968b2016-01-20 11:17:23 -05003749} // namespace gl