blob: 246ab66a23ddbc5fe354f0775b55cfb6ef58c154 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050029#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/ResourceManager.h"
31#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050032#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050033#include "libANGLE/Texture.h"
34#include "libANGLE/TransformFeedback.h"
35#include "libANGLE/VertexArray.h"
36#include "libANGLE/formatutils.h"
37#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070038#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040039#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040040#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030041#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040042#include "libANGLE/queryutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000043
Geoff Langf6db0982015-08-25 13:04:00 -040044namespace
45{
46
Ian Ewell3ffd78b2016-01-22 16:09:42 -050047template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050048std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030049 GLsizei numPaths,
50 const void *paths,
51 GLuint pathBase)
52{
53 std::vector<gl::Path *> ret;
54 ret.reserve(numPaths);
55
56 const auto *nameArray = static_cast<const T *>(paths);
57
58 for (GLsizei i = 0; i < numPaths; ++i)
59 {
60 const GLuint pathName = nameArray[i] + pathBase;
61
62 ret.push_back(resourceManager.getPath(pathName));
63 }
64
65 return ret;
66}
67
Geoff Lang4ddf5af2016-12-01 14:30:44 -050068std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030069 GLsizei numPaths,
70 GLenum pathNameType,
71 const void *paths,
72 GLuint pathBase)
73{
74 switch (pathNameType)
75 {
76 case GL_UNSIGNED_BYTE:
77 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
78
79 case GL_BYTE:
80 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
81
82 case GL_UNSIGNED_SHORT:
83 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_SHORT:
86 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_INT:
89 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_INT:
92 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
93 }
94
95 UNREACHABLE();
96 return std::vector<gl::Path *>();
97}
98
99template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400100gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500101{
Geoff Lang2186c382016-10-14 10:54:54 -0400102 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500103
104 switch (pname)
105 {
106 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400107 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500108 case GL_QUERY_RESULT_AVAILABLE_EXT:
109 {
110 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400111 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500112 if (!error.isError())
113 {
Geoff Lang2186c382016-10-14 10:54:54 -0400114 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500115 }
116 return error;
117 }
118 default:
119 UNREACHABLE();
120 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
121 }
122}
123
Geoff Langf6db0982015-08-25 13:04:00 -0400124void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
125{
Geoff Lang1a683462015-09-29 15:09:59 -0400126 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400127 {
128 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
129 tfBufferIndex++)
130 {
131 const OffsetBindingPointer<gl::Buffer> &buffer =
132 transformFeedback->getIndexedBuffer(tfBufferIndex);
133 if (buffer.get() != nullptr)
134 {
135 buffer->onTransformFeedback();
136 }
137 }
138 }
139}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140
141// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300142EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500143{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400144 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500145}
146
Martin Radev1be913c2016-07-11 17:59:16 +0300147EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
148{
149 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
150}
151
Geoff Langeb66a6e2016-10-31 13:06:12 -0400152gl::Version GetClientVersion(const egl::AttributeMap &attribs)
153{
154 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
155}
156
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500157GLenum GetResetStrategy(const egl::AttributeMap &attribs)
158{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400159 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
160 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500161 switch (attrib)
162 {
163 case EGL_NO_RESET_NOTIFICATION:
164 return GL_NO_RESET_NOTIFICATION_EXT;
165 case EGL_LOSE_CONTEXT_ON_RESET:
166 return GL_LOSE_CONTEXT_ON_RESET_EXT;
167 default:
168 UNREACHABLE();
169 return GL_NONE;
170 }
171}
172
173bool GetRobustAccess(const egl::AttributeMap &attribs)
174{
Geoff Lang077f20a2016-11-01 10:08:02 -0400175 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
176 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
177 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500178}
179
180bool GetDebug(const egl::AttributeMap &attribs)
181{
Geoff Lang077f20a2016-11-01 10:08:02 -0400182 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
183 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184}
185
186bool GetNoError(const egl::AttributeMap &attribs)
187{
188 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
189}
190
Geoff Langc287ea62016-09-16 14:46:51 -0400191bool GetWebGLContext(const egl::AttributeMap &attribs)
192{
193 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
194}
195
Geoff Langf41a7152016-09-19 15:11:17 -0400196bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
197{
198 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
199}
200
Martin Radev9d901792016-07-15 15:58:58 +0300201std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
202{
203 std::string labelName;
204 if (label != nullptr)
205 {
206 size_t labelLength = length < 0 ? strlen(label) : length;
207 labelName = std::string(label, labelLength);
208 }
209 return labelName;
210}
211
212void GetObjectLabelBase(const std::string &objectLabel,
213 GLsizei bufSize,
214 GLsizei *length,
215 GLchar *label)
216{
217 size_t writeLength = objectLabel.length();
218 if (label != nullptr && bufSize > 0)
219 {
220 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
221 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
222 label[writeLength] = '\0';
223 }
224
225 if (length != nullptr)
226 {
227 *length = static_cast<GLsizei>(writeLength);
228 }
229}
230
Geoff Langf6db0982015-08-25 13:04:00 -0400231} // anonymous namespace
232
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000233namespace gl
234{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000235
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400236Context::Context(rx::EGLImplFactory *implFactory,
237 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400238 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500239 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500240 const egl::AttributeMap &attribs,
241 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300242
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500243 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500244 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500245 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700246 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500247 mCaps,
248 mTextureCaps,
249 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500250 mLimitations,
251 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700252 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500253 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400254 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500255 mClientType(EGL_OPENGL_ES_API),
256 mHasBeenCurrent(false),
257 mContextLost(false),
258 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700259 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500260 mResetStrategy(GetResetStrategy(attribs)),
261 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500262 mCurrentSurface(nullptr),
263 mSurfacelessFramebuffer(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000264{
Geoff Lang077f20a2016-11-01 10:08:02 -0400265 if (mRobustAccess)
266 {
267 UNIMPLEMENTED();
268 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000269
Corentin Wallezc295e512017-01-27 17:47:50 -0500270 initCaps(GetWebGLContext(attribs), displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700271 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400272
Geoff Langeb66a6e2016-10-31 13:06:12 -0400273 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400274 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100275
Shannon Woods53a94a82014-06-24 15:20:36 -0400276 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400277
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000278 // [OpenGL ES 2.0.24] section 3.7 page 83:
279 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
280 // and cube map texture state vectors respectively associated with them.
281 // In order that access to these initial textures not be lost, they are treated as texture
282 // objects all of whose names are 0.
283
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400284 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500285 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500286
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400287 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500288 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400289
Geoff Langeb66a6e2016-10-31 13:06:12 -0400290 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400291 {
292 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400293 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500294 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400295
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400296 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500297 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400298 }
Geoff Lang3b573612016-10-31 14:08:10 -0400299 if (getClientVersion() >= Version(3, 1))
300 {
301 Texture *zeroTexture2DMultisample =
302 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
303 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
304 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000305
Ian Ewellbda75592016-04-18 17:25:54 -0400306 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
307 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400308 Texture *zeroTextureExternal =
309 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400310 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
311 }
312
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700313 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500314
Jamie Madill57a89722013-07-02 11:57:03 -0400315 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000316 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800317 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000318 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400319
Jamie Madill01a80ee2016-11-07 12:06:18 -0500320 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000321
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000322 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500323 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000324 {
325 bindIndexedUniformBuffer(0, i, 0, -1);
326 }
327
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000328 bindCopyReadBuffer(0);
329 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000330 bindPixelPackBuffer(0);
331 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000332
Geoff Langeb66a6e2016-10-31 13:06:12 -0400333 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400334 {
335 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
336 // In the initial state, a default transform feedback object is bound and treated as
337 // a transform feedback object with a name of zero. That object is bound any time
338 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400339 bindTransformFeedback(0);
340 }
Geoff Langc8058452014-02-03 12:04:11 -0500341
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700342 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500343
344 // Initialize dirty bit masks
345 // TODO(jmadill): additional ES3 state
346 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
347 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
348 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
349 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
350 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
351 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400352 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500353 // No dirty objects.
354
355 // Readpixels uses the pack state and read FBO
356 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
357 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
358 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
359 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
360 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400361 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500362 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
363
364 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
365 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
366 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
367 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
368 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
369 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
370 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
371 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
372 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
373 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
374 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
375 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
376
377 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
378 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700379 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500380 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
381 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400382
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400383 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000384}
385
Jamie Madill70ee0f62017-02-06 16:04:20 -0500386void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000387{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700388 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000389
Corentin Wallez80b24112015-08-25 16:41:57 -0400390 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000391 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400392 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000393 }
394
Corentin Wallez80b24112015-08-25 16:41:57 -0400395 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000396 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400397 if (query.second != nullptr)
398 {
399 query.second->release();
400 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000401 }
402
Corentin Wallez80b24112015-08-25 16:41:57 -0400403 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400404 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400405 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400406 }
407
Corentin Wallez80b24112015-08-25 16:41:57 -0400408 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500409 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500410 if (transformFeedback.second != nullptr)
411 {
412 transformFeedback.second->release();
413 }
Geoff Langc8058452014-02-03 12:04:11 -0500414 }
415
Jamie Madilldedd7b92014-11-05 16:30:36 -0500416 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400417 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500418 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400419 }
420 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421
Corentin Wallezccab69d2017-01-27 16:57:15 -0500422 SafeDelete(mSurfacelessFramebuffer);
423
Jamie Madill70ee0f62017-02-06 16:04:20 -0500424 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400425
Geoff Lang492a7e42014-11-05 13:27:06 -0500426 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427}
428
Jamie Madill70ee0f62017-02-06 16:04:20 -0500429Context::~Context()
430{
431}
432
433void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000434{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435 if (!mHasBeenCurrent)
436 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000437 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500438 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400439 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000440
Corentin Wallezc295e512017-01-27 17:47:50 -0500441 int width = 0;
442 int height = 0;
443 if (surface != nullptr)
444 {
445 width = surface->getWidth();
446 height = surface->getHeight();
447 }
448
449 mGLState.setViewportParams(0, 0, width, height);
450 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000451
452 mHasBeenCurrent = true;
453 }
454
Jamie Madill1b94d432015-08-07 13:23:23 -0400455 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700456 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400457
Jamie Madill70ee0f62017-02-06 16:04:20 -0500458 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500459
460 Framebuffer *newDefault = nullptr;
461 if (surface != nullptr)
462 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500463 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500464 mCurrentSurface = surface;
465 newDefault = surface->getDefaultFramebuffer();
466 }
467 else
468 {
469 if (mSurfacelessFramebuffer == nullptr)
470 {
471 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
472 }
473
474 newDefault = mSurfacelessFramebuffer;
475 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000476
Corentin Wallez37c39792015-08-20 14:19:46 -0400477 // Update default framebuffer, the binding of the previous default
478 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400479 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700480 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400481 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700482 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400483 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700484 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400485 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700486 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400487 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500488 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400489 }
Ian Ewell292f0052016-02-04 10:37:32 -0500490
491 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700492 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493}
494
Jamie Madill70ee0f62017-02-06 16:04:20 -0500495void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400496{
Corentin Wallez37c39792015-08-20 14:19:46 -0400497 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500498 Framebuffer *currentDefault = nullptr;
499 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400500 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500501 currentDefault = mCurrentSurface->getDefaultFramebuffer();
502 }
503 else if (mSurfacelessFramebuffer != nullptr)
504 {
505 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400506 }
507
Corentin Wallezc295e512017-01-27 17:47:50 -0500508 if (mGLState.getReadFramebuffer() == currentDefault)
509 {
510 mGLState.setReadFramebufferBinding(nullptr);
511 }
512 if (mGLState.getDrawFramebuffer() == currentDefault)
513 {
514 mGLState.setDrawFramebufferBinding(nullptr);
515 }
516 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
517
518 if (mCurrentSurface)
519 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500520 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500521 mCurrentSurface = nullptr;
522 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400523}
524
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000525GLuint Context::createBuffer()
526{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500527 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000528}
529
530GLuint Context::createProgram()
531{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500532 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000533}
534
535GLuint Context::createShader(GLenum type)
536{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500537 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000538}
539
540GLuint Context::createTexture()
541{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500542 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000543}
544
545GLuint Context::createRenderbuffer()
546{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500547 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000548}
549
Geoff Lang882033e2014-09-30 11:26:07 -0400550GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400551{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500552 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400553
Cooper Partind8e62a32015-01-29 15:21:25 -0800554 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400555}
556
Sami Väisänene45e53b2016-05-25 10:36:04 +0300557GLuint Context::createPaths(GLsizei range)
558{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500559 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300560 if (resultOrError.isError())
561 {
562 handleError(resultOrError.getError());
563 return 0;
564 }
565 return resultOrError.getResult();
566}
567
Jamie Madill57a89722013-07-02 11:57:03 -0400568GLuint Context::createVertexArray()
569{
Geoff Lang36167ab2015-12-07 10:27:14 -0500570 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
571 mVertexArrayMap[vertexArray] = nullptr;
572 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400573}
574
Jamie Madilldc356042013-07-19 16:36:57 -0400575GLuint Context::createSampler()
576{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500577 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400578}
579
Geoff Langc8058452014-02-03 12:04:11 -0500580GLuint Context::createTransformFeedback()
581{
Geoff Lang36167ab2015-12-07 10:27:14 -0500582 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
583 mTransformFeedbackMap[transformFeedback] = nullptr;
584 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500585}
586
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587// Returns an unused framebuffer name
588GLuint Context::createFramebuffer()
589{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500590 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000591}
592
Jamie Madill33dc8432013-07-26 11:55:05 -0400593GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000594{
Jamie Madill33dc8432013-07-26 11:55:05 -0400595 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000596
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400597 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000598
599 return handle;
600}
601
602// Returns an unused query name
603GLuint Context::createQuery()
604{
605 GLuint handle = mQueryHandleAllocator.allocate();
606
607 mQueryMap[handle] = NULL;
608
609 return handle;
610}
611
612void Context::deleteBuffer(GLuint buffer)
613{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500614 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000615 {
616 detachBuffer(buffer);
617 }
Jamie Madill893ab082014-05-16 16:56:10 -0400618
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800619 mState.mBuffers->deleteObject(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620}
621
622void Context::deleteShader(GLuint shader)
623{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500624 mState.mShaderPrograms->deleteShader(shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625}
626
627void Context::deleteProgram(GLuint program)
628{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500629 mState.mShaderPrograms->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630}
631
632void Context::deleteTexture(GLuint texture)
633{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500634 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000635 {
636 detachTexture(texture);
637 }
638
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800639 mState.mTextures->deleteObject(texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000640}
641
642void Context::deleteRenderbuffer(GLuint renderbuffer)
643{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500644 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000645 {
646 detachRenderbuffer(renderbuffer);
647 }
Jamie Madill893ab082014-05-16 16:56:10 -0400648
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800649 mState.mRenderbuffers->deleteObject(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000650}
651
Jamie Madillcd055f82013-07-26 11:55:15 -0400652void Context::deleteFenceSync(GLsync fenceSync)
653{
654 // The spec specifies the underlying Fence object is not deleted until all current
655 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
656 // and since our API is currently designed for being called from a single thread, we can delete
657 // the fence immediately.
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800658 mState.mFenceSyncs->deleteObject(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400659}
660
Sami Väisänene45e53b2016-05-25 10:36:04 +0300661void Context::deletePaths(GLuint first, GLsizei range)
662{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500663 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300664}
665
666bool Context::hasPathData(GLuint path) const
667{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500668 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300669 if (pathObj == nullptr)
670 return false;
671
672 return pathObj->hasPathData();
673}
674
675bool Context::hasPath(GLuint path) const
676{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500677 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300678}
679
680void Context::setPathCommands(GLuint path,
681 GLsizei numCommands,
682 const GLubyte *commands,
683 GLsizei numCoords,
684 GLenum coordType,
685 const void *coords)
686{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500687 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300688
689 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
690}
691
692void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
693{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500694 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300695
696 switch (pname)
697 {
698 case GL_PATH_STROKE_WIDTH_CHROMIUM:
699 pathObj->setStrokeWidth(value);
700 break;
701 case GL_PATH_END_CAPS_CHROMIUM:
702 pathObj->setEndCaps(static_cast<GLenum>(value));
703 break;
704 case GL_PATH_JOIN_STYLE_CHROMIUM:
705 pathObj->setJoinStyle(static_cast<GLenum>(value));
706 break;
707 case GL_PATH_MITER_LIMIT_CHROMIUM:
708 pathObj->setMiterLimit(value);
709 break;
710 case GL_PATH_STROKE_BOUND_CHROMIUM:
711 pathObj->setStrokeBound(value);
712 break;
713 default:
714 UNREACHABLE();
715 break;
716 }
717}
718
719void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
720{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500721 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300722
723 switch (pname)
724 {
725 case GL_PATH_STROKE_WIDTH_CHROMIUM:
726 *value = pathObj->getStrokeWidth();
727 break;
728 case GL_PATH_END_CAPS_CHROMIUM:
729 *value = static_cast<GLfloat>(pathObj->getEndCaps());
730 break;
731 case GL_PATH_JOIN_STYLE_CHROMIUM:
732 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
733 break;
734 case GL_PATH_MITER_LIMIT_CHROMIUM:
735 *value = pathObj->getMiterLimit();
736 break;
737 case GL_PATH_STROKE_BOUND_CHROMIUM:
738 *value = pathObj->getStrokeBound();
739 break;
740 default:
741 UNREACHABLE();
742 break;
743 }
744}
745
746void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
747{
748 mGLState.setPathStencilFunc(func, ref, mask);
749}
750
Jamie Madill57a89722013-07-02 11:57:03 -0400751void Context::deleteVertexArray(GLuint vertexArray)
752{
Geoff Lang36167ab2015-12-07 10:27:14 -0500753 auto iter = mVertexArrayMap.find(vertexArray);
754 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000755 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500756 VertexArray *vertexArrayObject = iter->second;
757 if (vertexArrayObject != nullptr)
758 {
759 detachVertexArray(vertexArray);
760 delete vertexArrayObject;
761 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000762
Geoff Lang36167ab2015-12-07 10:27:14 -0500763 mVertexArrayMap.erase(iter);
764 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400765 }
766}
767
Jamie Madilldc356042013-07-19 16:36:57 -0400768void Context::deleteSampler(GLuint sampler)
769{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500770 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400771 {
772 detachSampler(sampler);
773 }
774
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800775 mState.mSamplers->deleteObject(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400776}
777
Geoff Langc8058452014-02-03 12:04:11 -0500778void Context::deleteTransformFeedback(GLuint transformFeedback)
779{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500780 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500781 if (iter != mTransformFeedbackMap.end())
782 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500783 TransformFeedback *transformFeedbackObject = iter->second;
784 if (transformFeedbackObject != nullptr)
785 {
786 detachTransformFeedback(transformFeedback);
787 transformFeedbackObject->release();
788 }
789
Geoff Lang50b3fe82015-12-08 14:49:12 +0000790 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500791 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500792 }
793}
794
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795void Context::deleteFramebuffer(GLuint framebuffer)
796{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500797 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798 {
799 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500801
Jamie Madill5f45e7c2017-02-10 15:23:28 -0800802 mState.mFramebuffers->deleteObject(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000803}
804
Jamie Madill33dc8432013-07-26 11:55:05 -0400805void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000806{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500807 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000808
Jamie Madill33dc8432013-07-26 11:55:05 -0400809 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400811 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000812 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400813 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000814 }
815}
816
817void Context::deleteQuery(GLuint query)
818{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500819 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820 if (queryObject != mQueryMap.end())
821 {
822 mQueryHandleAllocator.release(queryObject->first);
823 if (queryObject->second)
824 {
825 queryObject->second->release();
826 }
827 mQueryMap.erase(queryObject);
828 }
829}
830
Geoff Lang70d0f492015-12-10 17:45:46 -0500831Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000832{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500833 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000834}
835
Jamie Madill570f7c82014-07-03 10:38:54 -0400836Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500838 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000839}
840
Geoff Lang70d0f492015-12-10 17:45:46 -0500841Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000842{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500843 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000844}
845
Jamie Madillcd055f82013-07-26 11:55:15 -0400846FenceSync *Context::getFenceSync(GLsync handle) const
847{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500848 return mState.mFenceSyncs->getFenceSync(
849 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400850}
851
Jamie Madill57a89722013-07-02 11:57:03 -0400852VertexArray *Context::getVertexArray(GLuint handle) const
853{
854 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500855 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400856}
857
Jamie Madilldc356042013-07-19 16:36:57 -0400858Sampler *Context::getSampler(GLuint handle) const
859{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500860 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400861}
862
Geoff Langc8058452014-02-03 12:04:11 -0500863TransformFeedback *Context::getTransformFeedback(GLuint handle) const
864{
Geoff Lang36167ab2015-12-07 10:27:14 -0500865 auto iter = mTransformFeedbackMap.find(handle);
866 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500867}
868
Geoff Lang70d0f492015-12-10 17:45:46 -0500869LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
870{
871 switch (identifier)
872 {
873 case GL_BUFFER:
874 return getBuffer(name);
875 case GL_SHADER:
876 return getShader(name);
877 case GL_PROGRAM:
878 return getProgram(name);
879 case GL_VERTEX_ARRAY:
880 return getVertexArray(name);
881 case GL_QUERY:
882 return getQuery(name);
883 case GL_TRANSFORM_FEEDBACK:
884 return getTransformFeedback(name);
885 case GL_SAMPLER:
886 return getSampler(name);
887 case GL_TEXTURE:
888 return getTexture(name);
889 case GL_RENDERBUFFER:
890 return getRenderbuffer(name);
891 case GL_FRAMEBUFFER:
892 return getFramebuffer(name);
893 default:
894 UNREACHABLE();
895 return nullptr;
896 }
897}
898
899LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
900{
901 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
902}
903
Martin Radev9d901792016-07-15 15:58:58 +0300904void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
905{
906 LabeledObject *object = getLabeledObject(identifier, name);
907 ASSERT(object != nullptr);
908
909 std::string labelName = GetObjectLabelFromPointer(length, label);
910 object->setLabel(labelName);
911}
912
913void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
914{
915 LabeledObject *object = getLabeledObjectFromPtr(ptr);
916 ASSERT(object != nullptr);
917
918 std::string labelName = GetObjectLabelFromPointer(length, label);
919 object->setLabel(labelName);
920}
921
922void Context::getObjectLabel(GLenum identifier,
923 GLuint name,
924 GLsizei bufSize,
925 GLsizei *length,
926 GLchar *label) const
927{
928 LabeledObject *object = getLabeledObject(identifier, name);
929 ASSERT(object != nullptr);
930
931 const std::string &objectLabel = object->getLabel();
932 GetObjectLabelBase(objectLabel, bufSize, length, label);
933}
934
935void Context::getObjectPtrLabel(const void *ptr,
936 GLsizei bufSize,
937 GLsizei *length,
938 GLchar *label) const
939{
940 LabeledObject *object = getLabeledObjectFromPtr(ptr);
941 ASSERT(object != nullptr);
942
943 const std::string &objectLabel = object->getLabel();
944 GetObjectLabelBase(objectLabel, bufSize, length, label);
945}
946
Jamie Madilldc356042013-07-19 16:36:57 -0400947bool Context::isSampler(GLuint samplerName) const
948{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500949 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400950}
951
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500952void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500954 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700955 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000956}
957
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800958void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
959{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500960 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800961 mGLState.setDrawIndirectBufferBinding(buffer);
962}
963
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500964void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000965{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500966 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700967 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000968}
969
Jamie Madilldedd7b92014-11-05 16:30:36 -0500970void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000971{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500972 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000973
Jamie Madilldedd7b92014-11-05 16:30:36 -0500974 if (handle == 0)
975 {
976 texture = mZeroTextures[target].get();
977 }
978 else
979 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500980 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500981 }
982
983 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700984 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000985}
986
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500987void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000988{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500989 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
990 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700991 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992}
993
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500994void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500996 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
997 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700998 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999}
1000
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001001void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001002{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001003 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001004 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001005}
1006
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001007void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001008{
Geoff Lang76b10c92014-09-05 16:28:14 -04001009 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001010 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001011 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001012 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001013}
1014
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001015void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001016{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001017 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001018 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001019}
1020
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001021void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1022 GLuint index,
1023 GLintptr offset,
1024 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001025{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001026 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001028}
1029
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001030void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001031{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001032 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001033 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001034}
1035
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001036void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1037 GLuint index,
1038 GLintptr offset,
1039 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001040{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001041 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001042 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001043}
1044
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001045void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001046{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001047 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001048 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001049}
1050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001051void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001052{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001053 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001054 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001055}
1056
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001057void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001058{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001059 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001060 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001061}
1062
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001063void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001064{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001065 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001066 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001067}
1068
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001069void Context::useProgram(GLuint program)
1070{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001071 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001072}
1073
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001074void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001075{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001076 TransformFeedback *transformFeedback =
1077 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001078 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001079}
1080
Geoff Lang5aad9672014-09-08 11:10:42 -04001081Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001082{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001083 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001084 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085
Geoff Lang5aad9672014-09-08 11:10:42 -04001086 // begin query
1087 Error error = queryObject->begin();
1088 if (error.isError())
1089 {
1090 return error;
1091 }
1092
1093 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001094 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095
He Yunchaoacd18982017-01-04 10:46:42 +08001096 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001097}
1098
Geoff Lang5aad9672014-09-08 11:10:42 -04001099Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001100{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001101 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001102 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001103
Geoff Lang5aad9672014-09-08 11:10:42 -04001104 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001105
Geoff Lang5aad9672014-09-08 11:10:42 -04001106 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001107 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001108
1109 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001110}
1111
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001112Error Context::queryCounter(GLuint id, GLenum target)
1113{
1114 ASSERT(target == GL_TIMESTAMP_EXT);
1115
1116 Query *queryObject = getQuery(id, true, target);
1117 ASSERT(queryObject);
1118
1119 return queryObject->queryCounter();
1120}
1121
1122void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1123{
1124 switch (pname)
1125 {
1126 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001127 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001128 break;
1129 case GL_QUERY_COUNTER_BITS_EXT:
1130 switch (target)
1131 {
1132 case GL_TIME_ELAPSED_EXT:
1133 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1134 break;
1135 case GL_TIMESTAMP_EXT:
1136 params[0] = getExtensions().queryCounterBitsTimestamp;
1137 break;
1138 default:
1139 UNREACHABLE();
1140 params[0] = 0;
1141 break;
1142 }
1143 break;
1144 default:
1145 UNREACHABLE();
1146 return;
1147 }
1148}
1149
Geoff Lang2186c382016-10-14 10:54:54 -04001150void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001151{
Geoff Lang2186c382016-10-14 10:54:54 -04001152 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001153}
1154
Geoff Lang2186c382016-10-14 10:54:54 -04001155void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001156{
Geoff Lang2186c382016-10-14 10:54:54 -04001157 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001158}
1159
Geoff Lang2186c382016-10-14 10:54:54 -04001160void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *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::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *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 Lang3bf8e3a2016-12-01 17:28:52 -05001170Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001172 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173}
1174
Jamie Madill33dc8432013-07-26 11:55:05 -04001175FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001176{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001177 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001178
Jamie Madill33dc8432013-07-26 11:55:05 -04001179 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180 {
1181 return NULL;
1182 }
1183 else
1184 {
1185 return fence->second;
1186 }
1187}
1188
1189Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1190{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001191 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001192
1193 if (query == mQueryMap.end())
1194 {
1195 return NULL;
1196 }
1197 else
1198 {
1199 if (!query->second && create)
1200 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001201 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001202 query->second->addRef();
1203 }
1204 return query->second;
1205 }
1206}
1207
Geoff Lang70d0f492015-12-10 17:45:46 -05001208Query *Context::getQuery(GLuint handle) const
1209{
1210 auto iter = mQueryMap.find(handle);
1211 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1212}
1213
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001214Texture *Context::getTargetTexture(GLenum target) const
1215{
Ian Ewellbda75592016-04-18 17:25:54 -04001216 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001217 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001218}
1219
Geoff Lang76b10c92014-09-05 16:28:14 -04001220Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001221{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001222 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223}
1224
Geoff Lang492a7e42014-11-05 13:27:06 -05001225Compiler *Context::getCompiler() const
1226{
1227 return mCompiler;
1228}
1229
Jamie Madill893ab082014-05-16 16:56:10 -04001230void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001231{
1232 switch (pname)
1233 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001234 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001235 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001237 mGLState.getBooleanv(pname, params);
1238 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001239 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240}
1241
Jamie Madill893ab082014-05-16 16:56:10 -04001242void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243{
Shannon Woods53a94a82014-06-24 15:20:36 -04001244 // Queries about context capabilities and maximums are answered by Context.
1245 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246 switch (pname)
1247 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001248 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001249 params[0] = mCaps.minAliasedLineWidth;
1250 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001251 break;
1252 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001253 params[0] = mCaps.minAliasedPointSize;
1254 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001256 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001257 ASSERT(mExtensions.textureFilterAnisotropic);
1258 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001259 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001260 case GL_MAX_TEXTURE_LOD_BIAS:
1261 *params = mCaps.maxLODBias;
1262 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001263
1264 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1265 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1266 {
1267 ASSERT(mExtensions.pathRendering);
1268 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1269 memcpy(params, m, 16 * sizeof(GLfloat));
1270 }
1271 break;
1272
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001274 mGLState.getFloatv(pname, params);
1275 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277}
1278
Jamie Madill893ab082014-05-16 16:56:10 -04001279void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280{
Shannon Woods53a94a82014-06-24 15:20:36 -04001281 // Queries about context capabilities and maximums are answered by Context.
1282 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001283
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284 switch (pname)
1285 {
Geoff Lang301d1612014-07-09 10:34:37 -04001286 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1287 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1288 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001289 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1290 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1291 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001292 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1293 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1294 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001295 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001296 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1297 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1298 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001299 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001300 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001301 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1302 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1303 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1304 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001305 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1306 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001307 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1308 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001309 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001310 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1311 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1312 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1313 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001314 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001315 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001316 break;
1317 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001318 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001319 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001320 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1321 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001322 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1323 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1324 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001325 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1326 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1327 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001328 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001329 case GL_MAX_VIEWPORT_DIMS:
1330 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001331 params[0] = mCaps.maxViewportWidth;
1332 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001333 }
1334 break;
1335 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001336 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001337 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001338 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1339 *params = mResetStrategy;
1340 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001341 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001342 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001343 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001344 case GL_SHADER_BINARY_FORMATS:
1345 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1346 break;
1347 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001348 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001349 break;
1350 case GL_PROGRAM_BINARY_FORMATS:
1351 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001352 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001353 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001354 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001355 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001356
1357 // GL_KHR_debug
1358 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1359 *params = mExtensions.maxDebugMessageLength;
1360 break;
1361 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1362 *params = mExtensions.maxDebugLoggedMessages;
1363 break;
1364 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1365 *params = mExtensions.maxDebugGroupStackDepth;
1366 break;
1367 case GL_MAX_LABEL_LENGTH:
1368 *params = mExtensions.maxLabelLength;
1369 break;
1370
Ian Ewell53f59f42016-01-28 17:36:55 -05001371 // GL_EXT_disjoint_timer_query
1372 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001373 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001374 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001375 case GL_MAX_FRAMEBUFFER_WIDTH:
1376 *params = mCaps.maxFramebufferWidth;
1377 break;
1378 case GL_MAX_FRAMEBUFFER_HEIGHT:
1379 *params = mCaps.maxFramebufferHeight;
1380 break;
1381 case GL_MAX_FRAMEBUFFER_SAMPLES:
1382 *params = mCaps.maxFramebufferSamples;
1383 break;
1384 case GL_MAX_SAMPLE_MASK_WORDS:
1385 *params = mCaps.maxSampleMaskWords;
1386 break;
1387 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1388 *params = mCaps.maxColorTextureSamples;
1389 break;
1390 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1391 *params = mCaps.maxDepthTextureSamples;
1392 break;
1393 case GL_MAX_INTEGER_SAMPLES:
1394 *params = mCaps.maxIntegerSamples;
1395 break;
1396 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1397 *params = mCaps.maxVertexAttribRelativeOffset;
1398 break;
1399 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1400 *params = mCaps.maxVertexAttribBindings;
1401 break;
1402 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1403 *params = mCaps.maxVertexAttribStride;
1404 break;
1405 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1406 *params = mCaps.maxVertexAtomicCounterBuffers;
1407 break;
1408 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1409 *params = mCaps.maxVertexAtomicCounters;
1410 break;
1411 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1412 *params = mCaps.maxVertexImageUniforms;
1413 break;
1414 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1415 *params = mCaps.maxVertexShaderStorageBlocks;
1416 break;
1417 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1418 *params = mCaps.maxFragmentAtomicCounterBuffers;
1419 break;
1420 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1421 *params = mCaps.maxFragmentAtomicCounters;
1422 break;
1423 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1424 *params = mCaps.maxFragmentImageUniforms;
1425 break;
1426 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1427 *params = mCaps.maxFragmentShaderStorageBlocks;
1428 break;
1429 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1430 *params = mCaps.minProgramTextureGatherOffset;
1431 break;
1432 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1433 *params = mCaps.maxProgramTextureGatherOffset;
1434 break;
1435 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1436 *params = mCaps.maxComputeWorkGroupInvocations;
1437 break;
1438 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1439 *params = mCaps.maxComputeUniformBlocks;
1440 break;
1441 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1442 *params = mCaps.maxComputeTextureImageUnits;
1443 break;
1444 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1445 *params = mCaps.maxComputeSharedMemorySize;
1446 break;
1447 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1448 *params = mCaps.maxComputeUniformComponents;
1449 break;
1450 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1451 *params = mCaps.maxComputeAtomicCounterBuffers;
1452 break;
1453 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1454 *params = mCaps.maxComputeAtomicCounters;
1455 break;
1456 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1457 *params = mCaps.maxComputeImageUniforms;
1458 break;
1459 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1460 *params = mCaps.maxCombinedComputeUniformComponents;
1461 break;
1462 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1463 *params = mCaps.maxComputeShaderStorageBlocks;
1464 break;
1465 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1466 *params = mCaps.maxCombinedShaderOutputResources;
1467 break;
1468 case GL_MAX_UNIFORM_LOCATIONS:
1469 *params = mCaps.maxUniformLocations;
1470 break;
1471 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1472 *params = mCaps.maxAtomicCounterBufferBindings;
1473 break;
1474 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1475 *params = mCaps.maxAtomicCounterBufferSize;
1476 break;
1477 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1478 *params = mCaps.maxCombinedAtomicCounterBuffers;
1479 break;
1480 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1481 *params = mCaps.maxCombinedAtomicCounters;
1482 break;
1483 case GL_MAX_IMAGE_UNITS:
1484 *params = mCaps.maxImageUnits;
1485 break;
1486 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1487 *params = mCaps.maxCombinedImageUniforms;
1488 break;
1489 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1490 *params = mCaps.maxShaderStorageBufferBindings;
1491 break;
1492 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1493 *params = mCaps.maxCombinedShaderStorageBlocks;
1494 break;
1495 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1496 *params = mCaps.shaderStorageBufferOffsetAlignment;
1497 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001498 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001499 mGLState.getIntegerv(mState, pname, params);
1500 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001501 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001502}
1503
Jamie Madill893ab082014-05-16 16:56:10 -04001504void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001505{
Shannon Woods53a94a82014-06-24 15:20:36 -04001506 // Queries about context capabilities and maximums are answered by Context.
1507 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001508 switch (pname)
1509 {
1510 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001511 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001512 break;
1513 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001514 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001515 break;
1516 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001517 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001518 break;
1519 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001520 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001521 break;
1522 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001523 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001524 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001525
1526 // GL_EXT_disjoint_timer_query
1527 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001528 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001529 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001530
1531 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1532 *params = mCaps.maxShaderStorageBlockSize;
1533 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001534 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001535 UNREACHABLE();
1536 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001537 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001538}
1539
Geoff Lang70d0f492015-12-10 17:45:46 -05001540void Context::getPointerv(GLenum pname, void **params) const
1541{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001542 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001543}
1544
Martin Radev66fb8202016-07-28 11:45:20 +03001545void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001546{
Shannon Woods53a94a82014-06-24 15:20:36 -04001547 // Queries about context capabilities and maximums are answered by Context.
1548 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001549
1550 GLenum nativeType;
1551 unsigned int numParams;
1552 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1553 ASSERT(queryStatus);
1554
1555 if (nativeType == GL_INT)
1556 {
1557 switch (target)
1558 {
1559 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1560 ASSERT(index < 3u);
1561 *data = mCaps.maxComputeWorkGroupCount[index];
1562 break;
1563 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1564 ASSERT(index < 3u);
1565 *data = mCaps.maxComputeWorkGroupSize[index];
1566 break;
1567 default:
1568 mGLState.getIntegeri_v(target, index, data);
1569 }
1570 }
1571 else
1572 {
1573 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1574 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001575}
1576
Martin Radev66fb8202016-07-28 11:45:20 +03001577void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001578{
Shannon Woods53a94a82014-06-24 15:20:36 -04001579 // Queries about context capabilities and maximums are answered by Context.
1580 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001581
1582 GLenum nativeType;
1583 unsigned int numParams;
1584 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1585 ASSERT(queryStatus);
1586
1587 if (nativeType == GL_INT_64_ANGLEX)
1588 {
1589 mGLState.getInteger64i_v(target, index, data);
1590 }
1591 else
1592 {
1593 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1594 }
1595}
1596
1597void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1598{
1599 // Queries about context capabilities and maximums are answered by Context.
1600 // Queries about current GL state values are answered by State.
1601
1602 GLenum nativeType;
1603 unsigned int numParams;
1604 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1605 ASSERT(queryStatus);
1606
1607 if (nativeType == GL_BOOL)
1608 {
1609 mGLState.getBooleani_v(target, index, data);
1610 }
1611 else
1612 {
1613 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1614 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001615}
1616
Jamie Madill675fe712016-12-19 13:07:54 -05001617void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001618{
Jamie Madill1b94d432015-08-07 13:23:23 -04001619 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001620 auto error = mImplementation->drawArrays(mode, first, count);
1621 handleError(error);
1622 if (!error.isError())
1623 {
1624 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1625 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001626}
1627
Jamie Madill675fe712016-12-19 13:07:54 -05001628void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001629{
1630 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001631 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1632 handleError(error);
1633 if (!error.isError())
1634 {
1635 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1636 }
Geoff Langf6db0982015-08-25 13:04:00 -04001637}
1638
Jamie Madill675fe712016-12-19 13:07:54 -05001639void Context::drawElements(GLenum mode,
1640 GLsizei count,
1641 GLenum type,
1642 const GLvoid *indices,
1643 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001644{
Jamie Madill1b94d432015-08-07 13:23:23 -04001645 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001646 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001647}
1648
Jamie Madill675fe712016-12-19 13:07:54 -05001649void Context::drawElementsInstanced(GLenum mode,
1650 GLsizei count,
1651 GLenum type,
1652 const GLvoid *indices,
1653 GLsizei instances,
1654 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001655{
1656 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001657 handleError(
1658 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001659}
1660
Jamie Madill675fe712016-12-19 13:07:54 -05001661void Context::drawRangeElements(GLenum mode,
1662 GLuint start,
1663 GLuint end,
1664 GLsizei count,
1665 GLenum type,
1666 const GLvoid *indices,
1667 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001668{
1669 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001670 handleError(
1671 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001672}
1673
Jiajia Qind9671222016-11-29 16:30:31 +08001674void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1675{
1676 syncRendererState();
1677 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1678}
1679
1680void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1681{
1682 syncRendererState();
1683 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1684}
1685
Jamie Madill675fe712016-12-19 13:07:54 -05001686void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001687{
Jamie Madill675fe712016-12-19 13:07:54 -05001688 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001689}
1690
Jamie Madill675fe712016-12-19 13:07:54 -05001691void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001692{
Jamie Madill675fe712016-12-19 13:07:54 -05001693 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001694}
1695
Austin Kinross6ee1e782015-05-29 17:05:37 -07001696void Context::insertEventMarker(GLsizei length, const char *marker)
1697{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001698 ASSERT(mImplementation);
1699 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001700}
1701
1702void Context::pushGroupMarker(GLsizei length, const char *marker)
1703{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001704 ASSERT(mImplementation);
1705 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001706}
1707
1708void Context::popGroupMarker()
1709{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001710 ASSERT(mImplementation);
1711 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001712}
1713
Geoff Langd8605522016-04-13 10:19:12 -04001714void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1715{
1716 Program *programObject = getProgram(program);
1717 ASSERT(programObject);
1718
1719 programObject->bindUniformLocation(location, name);
1720}
1721
Sami Väisänena797e062016-05-12 15:23:40 +03001722void Context::setCoverageModulation(GLenum components)
1723{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001724 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001725}
1726
Sami Väisänene45e53b2016-05-25 10:36:04 +03001727void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1728{
1729 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1730}
1731
1732void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1733{
1734 GLfloat I[16];
1735 angle::Matrix<GLfloat>::setToIdentity(I);
1736
1737 mGLState.loadPathRenderingMatrix(matrixMode, I);
1738}
1739
1740void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1741{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001742 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001743 if (!pathObj)
1744 return;
1745
1746 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1747 syncRendererState();
1748
1749 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1750}
1751
1752void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1753{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001754 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001755 if (!pathObj)
1756 return;
1757
1758 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1759 syncRendererState();
1760
1761 mImplementation->stencilStrokePath(pathObj, reference, mask);
1762}
1763
1764void Context::coverFillPath(GLuint path, GLenum coverMode)
1765{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001766 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001767 if (!pathObj)
1768 return;
1769
1770 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1771 syncRendererState();
1772
1773 mImplementation->coverFillPath(pathObj, coverMode);
1774}
1775
1776void Context::coverStrokePath(GLuint path, GLenum coverMode)
1777{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001778 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001779 if (!pathObj)
1780 return;
1781
1782 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1783 syncRendererState();
1784
1785 mImplementation->coverStrokePath(pathObj, coverMode);
1786}
1787
1788void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1789{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001790 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001791 if (!pathObj)
1792 return;
1793
1794 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1795 syncRendererState();
1796
1797 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1798}
1799
1800void Context::stencilThenCoverStrokePath(GLuint path,
1801 GLint reference,
1802 GLuint mask,
1803 GLenum coverMode)
1804{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001805 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001806 if (!pathObj)
1807 return;
1808
1809 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1810 syncRendererState();
1811
1812 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1813}
1814
Sami Väisänend59ca052016-06-21 16:10:00 +03001815void Context::coverFillPathInstanced(GLsizei numPaths,
1816 GLenum pathNameType,
1817 const void *paths,
1818 GLuint pathBase,
1819 GLenum coverMode,
1820 GLenum transformType,
1821 const GLfloat *transformValues)
1822{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001823 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001824
1825 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1826 syncRendererState();
1827
1828 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1829}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001830
Sami Väisänend59ca052016-06-21 16:10:00 +03001831void Context::coverStrokePathInstanced(GLsizei numPaths,
1832 GLenum pathNameType,
1833 const void *paths,
1834 GLuint pathBase,
1835 GLenum coverMode,
1836 GLenum transformType,
1837 const GLfloat *transformValues)
1838{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001839 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001840
1841 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1842 syncRendererState();
1843
1844 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1845 transformValues);
1846}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001847
Sami Väisänend59ca052016-06-21 16:10:00 +03001848void Context::stencilFillPathInstanced(GLsizei numPaths,
1849 GLenum pathNameType,
1850 const void *paths,
1851 GLuint pathBase,
1852 GLenum fillMode,
1853 GLuint mask,
1854 GLenum transformType,
1855 const GLfloat *transformValues)
1856{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001857 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001858
1859 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1860 syncRendererState();
1861
1862 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1863 transformValues);
1864}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001865
Sami Väisänend59ca052016-06-21 16:10:00 +03001866void Context::stencilStrokePathInstanced(GLsizei numPaths,
1867 GLenum pathNameType,
1868 const void *paths,
1869 GLuint pathBase,
1870 GLint reference,
1871 GLuint mask,
1872 GLenum transformType,
1873 const GLfloat *transformValues)
1874{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001875 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001876
1877 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1878 syncRendererState();
1879
1880 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1881 transformValues);
1882}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001883
Sami Väisänend59ca052016-06-21 16:10:00 +03001884void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1885 GLenum pathNameType,
1886 const void *paths,
1887 GLuint pathBase,
1888 GLenum fillMode,
1889 GLuint mask,
1890 GLenum coverMode,
1891 GLenum transformType,
1892 const GLfloat *transformValues)
1893{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001894 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001895
1896 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1897 syncRendererState();
1898
1899 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1900 transformType, transformValues);
1901}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001902
Sami Väisänend59ca052016-06-21 16:10:00 +03001903void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1904 GLenum pathNameType,
1905 const void *paths,
1906 GLuint pathBase,
1907 GLint reference,
1908 GLuint mask,
1909 GLenum coverMode,
1910 GLenum transformType,
1911 const GLfloat *transformValues)
1912{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001913 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001914
1915 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1916 syncRendererState();
1917
1918 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1919 transformType, transformValues);
1920}
1921
Sami Väisänen46eaa942016-06-29 10:26:37 +03001922void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1923{
1924 auto *programObject = getProgram(program);
1925
1926 programObject->bindFragmentInputLocation(location, name);
1927}
1928
1929void Context::programPathFragmentInputGen(GLuint program,
1930 GLint location,
1931 GLenum genMode,
1932 GLint components,
1933 const GLfloat *coeffs)
1934{
1935 auto *programObject = getProgram(program);
1936
1937 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1938}
1939
Jamie Madill437fa652016-05-03 15:13:24 -04001940void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001941{
Geoff Langda5777c2014-07-11 09:52:58 -04001942 if (error.isError())
1943 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001944 GLenum code = error.getCode();
1945 mErrors.insert(code);
1946 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1947 {
1948 markContextLost();
1949 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001950
1951 if (!error.getMessage().empty())
1952 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001953 auto *debug = &mGLState.getDebug();
1954 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1955 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001956 }
Geoff Langda5777c2014-07-11 09:52:58 -04001957 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001958}
1959
1960// Get one of the recorded errors and clear its flag, if any.
1961// [OpenGL ES 2.0.24] section 2.5 page 13.
1962GLenum Context::getError()
1963{
Geoff Langda5777c2014-07-11 09:52:58 -04001964 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001965 {
Geoff Langda5777c2014-07-11 09:52:58 -04001966 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001967 }
Geoff Langda5777c2014-07-11 09:52:58 -04001968 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001969 {
Geoff Langda5777c2014-07-11 09:52:58 -04001970 GLenum error = *mErrors.begin();
1971 mErrors.erase(mErrors.begin());
1972 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001973 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001974}
1975
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001976// NOTE: this function should not assume that this context is current!
1977void Context::markContextLost()
1978{
1979 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001980 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001981 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001982 mContextLostForced = true;
1983 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001984 mContextLost = true;
1985}
1986
1987bool Context::isContextLost()
1988{
1989 return mContextLost;
1990}
1991
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001992GLenum Context::getResetStatus()
1993{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001994 // Even if the application doesn't want to know about resets, we want to know
1995 // as it will allow us to skip all the calls.
1996 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001997 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001998 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001999 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002000 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002001 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002002
2003 // EXT_robustness, section 2.6: If the reset notification behavior is
2004 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2005 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2006 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002007 }
2008
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002009 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2010 // status should be returned at least once, and GL_NO_ERROR should be returned
2011 // once the device has finished resetting.
2012 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002013 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002014 ASSERT(mResetStatus == GL_NO_ERROR);
2015 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002016
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002017 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002018 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002019 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002020 }
2021 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002022 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002023 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002024 // If markContextLost was used to mark the context lost then
2025 // assume that is not recoverable, and continue to report the
2026 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002027 mResetStatus = mImplementation->getResetStatus();
2028 }
Jamie Madill893ab082014-05-16 16:56:10 -04002029
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002030 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002031}
2032
2033bool Context::isResetNotificationEnabled()
2034{
2035 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2036}
2037
Corentin Walleze3b10e82015-05-20 11:06:25 -04002038const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002039{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002040 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002041}
2042
2043EGLenum Context::getClientType() const
2044{
2045 return mClientType;
2046}
2047
2048EGLenum Context::getRenderBuffer() const
2049{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002050 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2051 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002052 {
2053 return EGL_NONE;
2054 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002055
2056 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2057 ASSERT(backAttachment != nullptr);
2058 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002059}
2060
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002061VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002062{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002063 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002064 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2065 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002066 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002067 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2068
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002069 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002070 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002071
2072 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002073}
2074
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002075TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002076{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002077 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002078 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2079 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002080 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002081 transformFeedback =
2082 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002083 transformFeedback->addRef();
2084 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002085 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002086
2087 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002088}
2089
2090bool Context::isVertexArrayGenerated(GLuint vertexArray)
2091{
Geoff Langf41a7152016-09-19 15:11:17 -04002092 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002093 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2094}
2095
2096bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2097{
Geoff Langf41a7152016-09-19 15:11:17 -04002098 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002099 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2100}
2101
Shannon Woods53a94a82014-06-24 15:20:36 -04002102void Context::detachTexture(GLuint texture)
2103{
2104 // Simple pass-through to State's detachTexture method, as textures do not require
2105 // allocation map management either here or in the resource manager at detach time.
2106 // Zero textures are held by the Context, and we don't attempt to request them from
2107 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002108 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002109}
2110
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002111void Context::detachBuffer(GLuint buffer)
2112{
Yuly Novikov5807a532015-12-03 13:01:22 -05002113 // Simple pass-through to State's detachBuffer method, since
2114 // only buffer attachments to container objects that are bound to the current context
2115 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002116
Yuly Novikov5807a532015-12-03 13:01:22 -05002117 // [OpenGL ES 3.2] section 5.1.2 page 45:
2118 // Attachments to unbound container objects, such as
2119 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2120 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002121 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002122}
2123
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002124void Context::detachFramebuffer(GLuint framebuffer)
2125{
Shannon Woods53a94a82014-06-24 15:20:36 -04002126 // Framebuffer detachment is handled by Context, because 0 is a valid
2127 // Framebuffer object, and a pointer to it must be passed from Context
2128 // to State at binding time.
2129
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002130 // [OpenGL ES 2.0.24] section 4.4 page 107:
2131 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2132 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2133
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002134 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002135 {
2136 bindReadFramebuffer(0);
2137 }
2138
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002139 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002140 {
2141 bindDrawFramebuffer(0);
2142 }
2143}
2144
2145void Context::detachRenderbuffer(GLuint renderbuffer)
2146{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002147 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002148}
2149
Jamie Madill57a89722013-07-02 11:57:03 -04002150void Context::detachVertexArray(GLuint vertexArray)
2151{
Jamie Madill77a72f62015-04-14 11:18:32 -04002152 // Vertex array detachment is handled by Context, because 0 is a valid
2153 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002154 // binding time.
2155
Jamie Madill57a89722013-07-02 11:57:03 -04002156 // [OpenGL ES 3.0.2] section 2.10 page 43:
2157 // If a vertex array object that is currently bound is deleted, the binding
2158 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002159 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002160 {
2161 bindVertexArray(0);
2162 }
2163}
2164
Geoff Langc8058452014-02-03 12:04:11 -05002165void Context::detachTransformFeedback(GLuint transformFeedback)
2166{
Corentin Walleza2257da2016-04-19 16:43:12 -04002167 // Transform feedback detachment is handled by Context, because 0 is a valid
2168 // transform feedback, and a pointer to it must be passed from Context to State at
2169 // binding time.
2170
2171 // The OpenGL specification doesn't mention what should happen when the currently bound
2172 // transform feedback object is deleted. Since it is a container object, we treat it like
2173 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002174 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002175 {
2176 bindTransformFeedback(0);
2177 }
Geoff Langc8058452014-02-03 12:04:11 -05002178}
2179
Jamie Madilldc356042013-07-19 16:36:57 -04002180void Context::detachSampler(GLuint sampler)
2181{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002182 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002183}
2184
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002185void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2186{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002187 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002188}
2189
Jamie Madille29d1672013-07-19 16:36:57 -04002190void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2191{
Geoff Langc1984ed2016-10-07 12:41:00 -04002192 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002193 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002194 SetSamplerParameteri(samplerObject, pname, param);
2195}
Jamie Madille29d1672013-07-19 16:36:57 -04002196
Geoff Langc1984ed2016-10-07 12:41:00 -04002197void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2198{
2199 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002200 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002201 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002202}
2203
2204void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2205{
Geoff Langc1984ed2016-10-07 12:41:00 -04002206 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002207 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002208 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002209}
2210
Geoff Langc1984ed2016-10-07 12:41:00 -04002211void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002212{
Geoff Langc1984ed2016-10-07 12:41:00 -04002213 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002214 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002215 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002216}
2217
Geoff Langc1984ed2016-10-07 12:41:00 -04002218void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002219{
Geoff Langc1984ed2016-10-07 12:41:00 -04002220 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002221 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002222 QuerySamplerParameteriv(samplerObject, pname, params);
2223}
Jamie Madill9675b802013-07-19 16:36:59 -04002224
Geoff Langc1984ed2016-10-07 12:41:00 -04002225void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2226{
2227 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002228 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002229 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002230}
2231
Olli Etuahof0fee072016-03-30 15:11:58 +03002232void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2233{
2234 gl::Program *programObject = getProgram(program);
2235 ASSERT(programObject != nullptr);
2236
2237 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2238 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2239}
2240
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002241void Context::initRendererString()
2242{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002243 std::ostringstream rendererString;
2244 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002245 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002246 rendererString << ")";
2247
Geoff Langcec35902014-04-16 10:52:36 -04002248 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002249}
2250
Geoff Langc339c4e2016-11-29 10:37:36 -05002251void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002252{
Geoff Langc339c4e2016-11-29 10:37:36 -05002253 const Version &clientVersion = getClientVersion();
2254
2255 std::ostringstream versionString;
2256 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2257 << ANGLE_VERSION_STRING << ")";
2258 mVersionString = MakeStaticString(versionString.str());
2259
2260 std::ostringstream shadingLanguageVersionString;
2261 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2262 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2263 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2264 << ")";
2265 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002266}
2267
Geoff Langcec35902014-04-16 10:52:36 -04002268void Context::initExtensionStrings()
2269{
Geoff Langc339c4e2016-11-29 10:37:36 -05002270 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2271 std::ostringstream combinedStringStream;
2272 std::copy(strings.begin(), strings.end(),
2273 std::ostream_iterator<const char *>(combinedStringStream, " "));
2274 return MakeStaticString(combinedStringStream.str());
2275 };
2276
2277 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002278 for (const auto &extensionString : mExtensions.getStrings())
2279 {
2280 mExtensionStrings.push_back(MakeStaticString(extensionString));
2281 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002282 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002283
Bryan Bernhart58806562017-01-05 13:09:31 -08002284 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2285
Geoff Langc339c4e2016-11-29 10:37:36 -05002286 mRequestableExtensionStrings.clear();
2287 for (const auto &extensionInfo : GetExtensionInfoMap())
2288 {
2289 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002290 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2291 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002292 {
2293 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2294 }
2295 }
2296 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002297}
2298
Geoff Langc339c4e2016-11-29 10:37:36 -05002299const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002300{
Geoff Langc339c4e2016-11-29 10:37:36 -05002301 switch (name)
2302 {
2303 case GL_VENDOR:
2304 return reinterpret_cast<const GLubyte *>("Google Inc.");
2305
2306 case GL_RENDERER:
2307 return reinterpret_cast<const GLubyte *>(mRendererString);
2308
2309 case GL_VERSION:
2310 return reinterpret_cast<const GLubyte *>(mVersionString);
2311
2312 case GL_SHADING_LANGUAGE_VERSION:
2313 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2314
2315 case GL_EXTENSIONS:
2316 return reinterpret_cast<const GLubyte *>(mExtensionString);
2317
2318 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2319 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2320
2321 default:
2322 UNREACHABLE();
2323 return nullptr;
2324 }
Geoff Langcec35902014-04-16 10:52:36 -04002325}
2326
Geoff Langc339c4e2016-11-29 10:37:36 -05002327const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002328{
Geoff Langc339c4e2016-11-29 10:37:36 -05002329 switch (name)
2330 {
2331 case GL_EXTENSIONS:
2332 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2333
2334 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2335 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2336
2337 default:
2338 UNREACHABLE();
2339 return nullptr;
2340 }
Geoff Langcec35902014-04-16 10:52:36 -04002341}
2342
2343size_t Context::getExtensionStringCount() const
2344{
2345 return mExtensionStrings.size();
2346}
2347
Geoff Langc339c4e2016-11-29 10:37:36 -05002348void Context::requestExtension(const char *name)
2349{
2350 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2351 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2352 const auto &extension = extensionInfos.at(name);
2353 ASSERT(extension.Requestable);
2354
2355 if (mExtensions.*(extension.ExtensionsMember))
2356 {
2357 // Extension already enabled
2358 return;
2359 }
2360
2361 mExtensions.*(extension.ExtensionsMember) = true;
2362 updateCaps();
2363 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002364
2365 // Re-create the compiler with the requested extensions enabled.
2366 SafeDelete(mCompiler);
2367 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002368}
2369
2370size_t Context::getRequestableExtensionStringCount() const
2371{
2372 return mRequestableExtensionStrings.size();
2373}
2374
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002375void Context::beginTransformFeedback(GLenum primitiveMode)
2376{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002377 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002378 ASSERT(transformFeedback != nullptr);
2379 ASSERT(!transformFeedback->isPaused());
2380
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002381 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002382}
2383
2384bool Context::hasActiveTransformFeedback(GLuint program) const
2385{
2386 for (auto pair : mTransformFeedbackMap)
2387 {
2388 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2389 {
2390 return true;
2391 }
2392 }
2393 return false;
2394}
2395
Corentin Wallezc295e512017-01-27 17:47:50 -05002396void Context::initCaps(bool webGLContext, const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002397{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002398 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002399
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002400 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002401
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002402 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002403
Geoff Langeb66a6e2016-10-31 13:06:12 -04002404 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002405 {
2406 // Disable ES3+ extensions
2407 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002408 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002409 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002410 }
2411
Geoff Langeb66a6e2016-10-31 13:06:12 -04002412 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002413 {
2414 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2415 //mExtensions.sRGB = false;
2416 }
2417
Jamie Madill00ed7a12016-05-19 13:13:38 -04002418 // Some extensions are always available because they are implemented in the GL layer.
2419 mExtensions.bindUniformLocation = true;
2420 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002421 mExtensions.bindGeneratesResource = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002422 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002423
2424 // Enable the no error extension if the context was created with the flag.
2425 mExtensions.noError = mSkipValidation;
2426
Corentin Wallezccab69d2017-01-27 16:57:15 -05002427 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002428 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002429
Geoff Lang70d0f492015-12-10 17:45:46 -05002430 // Explicitly enable GL_KHR_debug
2431 mExtensions.debug = true;
2432 mExtensions.maxDebugMessageLength = 1024;
2433 mExtensions.maxDebugLoggedMessages = 1024;
2434 mExtensions.maxDebugGroupStackDepth = 1024;
2435 mExtensions.maxLabelLength = 1024;
2436
Geoff Langff5b2d52016-09-07 11:32:23 -04002437 // Explicitly enable GL_ANGLE_robust_client_memory
2438 mExtensions.robustClientMemory = true;
2439
Geoff Lang301d1612014-07-09 10:34:37 -04002440 // Apply implementation limits
2441 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002442 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2443 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2444
2445 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002446
Geoff Langc287ea62016-09-16 14:46:51 -04002447 // WebGL compatibility
2448 mExtensions.webglCompatibility = webGLContext;
2449 for (const auto &extensionInfo : GetExtensionInfoMap())
2450 {
2451 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002452 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002453 {
2454 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2455 }
2456 }
2457
2458 // Generate texture caps
2459 updateCaps();
2460}
2461
2462void Context::updateCaps()
2463{
Geoff Lang900013c2014-07-07 11:32:19 -04002464 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002465 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002466
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002467 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002468 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2469 {
2470 GLenum format = i->first;
2471 TextureCaps formatCaps = i->second;
2472
Geoff Lang5d601382014-07-22 15:14:06 -04002473 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002474
Geoff Lang0d8b7242015-09-09 14:56:53 -04002475 // Update the format caps based on the client version and extensions.
2476 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2477 // ES3.
2478 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002479 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002480 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002481 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002482 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002483 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002484
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002485 // OpenGL ES does not support multisampling with non-rendererable formats
2486 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2487 if (!formatInfo.renderSupport ||
2488 (getClientVersion() < ES_3_1 &&
2489 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002490 {
Geoff Langd87878e2014-09-19 15:42:59 -04002491 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002492 }
Geoff Langd87878e2014-09-19 15:42:59 -04002493
2494 if (formatCaps.texturable && formatInfo.compressed)
2495 {
2496 mCaps.compressedTextureFormats.push_back(format);
2497 }
2498
2499 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002500 }
2501}
2502
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002503void Context::initWorkarounds()
2504{
2505 // Lose the context upon out of memory error if the application is
2506 // expecting to watch for those events.
2507 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2508}
2509
Jamie Madill1b94d432015-08-07 13:23:23 -04002510void Context::syncRendererState()
2511{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002512 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2513 mImplementation->syncState(mGLState, dirtyBits);
2514 mGLState.clearDirtyBits();
2515 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002516}
2517
Jamie Madillad9f24e2016-02-12 09:27:24 -05002518void Context::syncRendererState(const State::DirtyBits &bitMask,
2519 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002520{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002521 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2522 mImplementation->syncState(mGLState, dirtyBits);
2523 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002524
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002525 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002526}
Jamie Madillc29968b2016-01-20 11:17:23 -05002527
2528void Context::blitFramebuffer(GLint srcX0,
2529 GLint srcY0,
2530 GLint srcX1,
2531 GLint srcY1,
2532 GLint dstX0,
2533 GLint dstY0,
2534 GLint dstX1,
2535 GLint dstY1,
2536 GLbitfield mask,
2537 GLenum filter)
2538{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002539 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002540 ASSERT(drawFramebuffer);
2541
2542 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2543 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2544
Jamie Madillad9f24e2016-02-12 09:27:24 -05002545 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002546
Jamie Madill8415b5f2016-04-26 13:41:39 -04002547 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002548}
Jamie Madillc29968b2016-01-20 11:17:23 -05002549
2550void Context::clear(GLbitfield mask)
2551{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002552 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002553 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002554}
2555
2556void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2557{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002558 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002559 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2560 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002561}
2562
2563void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2564{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002565 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002566 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2567 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002568}
2569
2570void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2571{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002572 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002573 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2574 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002575}
2576
2577void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2578{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002579 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002580 ASSERT(framebufferObject);
2581
2582 // If a buffer is not present, the clear has no effect
2583 if (framebufferObject->getDepthbuffer() == nullptr &&
2584 framebufferObject->getStencilbuffer() == nullptr)
2585 {
2586 return;
2587 }
2588
Jamie Madillad9f24e2016-02-12 09:27:24 -05002589 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002590 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2591 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002592}
2593
2594void Context::readPixels(GLint x,
2595 GLint y,
2596 GLsizei width,
2597 GLsizei height,
2598 GLenum format,
2599 GLenum type,
2600 GLvoid *pixels)
2601{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002602 if (width == 0 || height == 0)
2603 {
2604 return;
2605 }
2606
Jamie Madillad9f24e2016-02-12 09:27:24 -05002607 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002608
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002609 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002610 ASSERT(framebufferObject);
2611
2612 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002613 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002614}
2615
2616void Context::copyTexImage2D(GLenum target,
2617 GLint level,
2618 GLenum internalformat,
2619 GLint x,
2620 GLint y,
2621 GLsizei width,
2622 GLsizei height,
2623 GLint border)
2624{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002625 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002626 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002627
Jamie Madillc29968b2016-01-20 11:17:23 -05002628 Rectangle sourceArea(x, y, width, height);
2629
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002630 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002631 Texture *texture =
2632 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002633 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002634}
2635
2636void Context::copyTexSubImage2D(GLenum target,
2637 GLint level,
2638 GLint xoffset,
2639 GLint yoffset,
2640 GLint x,
2641 GLint y,
2642 GLsizei width,
2643 GLsizei height)
2644{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002645 if (width == 0 || height == 0)
2646 {
2647 return;
2648 }
2649
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002650 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002651 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002652
Jamie Madillc29968b2016-01-20 11:17:23 -05002653 Offset destOffset(xoffset, yoffset, 0);
2654 Rectangle sourceArea(x, y, width, height);
2655
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002656 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002657 Texture *texture =
2658 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002659 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002660}
2661
2662void Context::copyTexSubImage3D(GLenum target,
2663 GLint level,
2664 GLint xoffset,
2665 GLint yoffset,
2666 GLint zoffset,
2667 GLint x,
2668 GLint y,
2669 GLsizei width,
2670 GLsizei height)
2671{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002672 if (width == 0 || height == 0)
2673 {
2674 return;
2675 }
2676
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002677 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002678 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002679
Jamie Madillc29968b2016-01-20 11:17:23 -05002680 Offset destOffset(xoffset, yoffset, zoffset);
2681 Rectangle sourceArea(x, y, width, height);
2682
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002683 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002684 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002685 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002686}
2687
2688void Context::framebufferTexture2D(GLenum target,
2689 GLenum attachment,
2690 GLenum textarget,
2691 GLuint texture,
2692 GLint level)
2693{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002694 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002695 ASSERT(framebuffer);
2696
2697 if (texture != 0)
2698 {
2699 Texture *textureObj = getTexture(texture);
2700
2701 ImageIndex index = ImageIndex::MakeInvalid();
2702
2703 if (textarget == GL_TEXTURE_2D)
2704 {
2705 index = ImageIndex::Make2D(level);
2706 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002707 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2708 {
2709 ASSERT(level == 0);
2710 index = ImageIndex::Make2DMultisample();
2711 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002712 else
2713 {
2714 ASSERT(IsCubeMapTextureTarget(textarget));
2715 index = ImageIndex::MakeCube(textarget, level);
2716 }
2717
2718 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2719 }
2720 else
2721 {
2722 framebuffer->resetAttachment(attachment);
2723 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002724
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002725 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002726}
2727
2728void Context::framebufferRenderbuffer(GLenum target,
2729 GLenum attachment,
2730 GLenum renderbuffertarget,
2731 GLuint renderbuffer)
2732{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002733 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002734 ASSERT(framebuffer);
2735
2736 if (renderbuffer != 0)
2737 {
2738 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2739 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2740 renderbufferObject);
2741 }
2742 else
2743 {
2744 framebuffer->resetAttachment(attachment);
2745 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002746
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002747 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002748}
2749
2750void Context::framebufferTextureLayer(GLenum target,
2751 GLenum attachment,
2752 GLuint texture,
2753 GLint level,
2754 GLint layer)
2755{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002756 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002757 ASSERT(framebuffer);
2758
2759 if (texture != 0)
2760 {
2761 Texture *textureObject = getTexture(texture);
2762
2763 ImageIndex index = ImageIndex::MakeInvalid();
2764
2765 if (textureObject->getTarget() == GL_TEXTURE_3D)
2766 {
2767 index = ImageIndex::Make3D(level, layer);
2768 }
2769 else
2770 {
2771 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2772 index = ImageIndex::Make2DArray(level, layer);
2773 }
2774
2775 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2776 }
2777 else
2778 {
2779 framebuffer->resetAttachment(attachment);
2780 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002781
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002782 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002783}
2784
2785void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2786{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002787 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002788 ASSERT(framebuffer);
2789 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002790 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002791}
2792
2793void Context::readBuffer(GLenum mode)
2794{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002795 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002796 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002797 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002798}
2799
2800void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2801{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002802 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002803 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002804
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002805 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002806 ASSERT(framebuffer);
2807
2808 // The specification isn't clear what should be done when the framebuffer isn't complete.
2809 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002810 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002811}
2812
2813void Context::invalidateFramebuffer(GLenum target,
2814 GLsizei numAttachments,
2815 const GLenum *attachments)
2816{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002817 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002818 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002819
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002820 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002821 ASSERT(framebuffer);
2822
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002823 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002824 {
Jamie Madill437fa652016-05-03 15:13:24 -04002825 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002826 }
Jamie Madill437fa652016-05-03 15:13:24 -04002827
2828 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002829}
2830
2831void Context::invalidateSubFramebuffer(GLenum target,
2832 GLsizei numAttachments,
2833 const GLenum *attachments,
2834 GLint x,
2835 GLint y,
2836 GLsizei width,
2837 GLsizei height)
2838{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002839 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002840 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002841
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002842 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002843 ASSERT(framebuffer);
2844
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002845 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002846 {
Jamie Madill437fa652016-05-03 15:13:24 -04002847 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002848 }
Jamie Madill437fa652016-05-03 15:13:24 -04002849
2850 Rectangle area(x, y, width, height);
2851 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002852}
2853
Jamie Madill73a84962016-02-12 09:27:23 -05002854void Context::texImage2D(GLenum target,
2855 GLint level,
2856 GLint internalformat,
2857 GLsizei width,
2858 GLsizei height,
2859 GLint border,
2860 GLenum format,
2861 GLenum type,
2862 const GLvoid *pixels)
2863{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002864 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002865
2866 Extents size(width, height, 1);
2867 Texture *texture =
2868 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002869 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2870 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002871}
2872
2873void Context::texImage3D(GLenum target,
2874 GLint level,
2875 GLint internalformat,
2876 GLsizei width,
2877 GLsizei height,
2878 GLsizei depth,
2879 GLint border,
2880 GLenum format,
2881 GLenum type,
2882 const GLvoid *pixels)
2883{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002884 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002885
2886 Extents size(width, height, depth);
2887 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002888 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2889 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002890}
2891
2892void Context::texSubImage2D(GLenum target,
2893 GLint level,
2894 GLint xoffset,
2895 GLint yoffset,
2896 GLsizei width,
2897 GLsizei height,
2898 GLenum format,
2899 GLenum type,
2900 const GLvoid *pixels)
2901{
2902 // Zero sized uploads are valid but no-ops
2903 if (width == 0 || height == 0)
2904 {
2905 return;
2906 }
2907
Jamie Madillad9f24e2016-02-12 09:27:24 -05002908 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002909
2910 Box area(xoffset, yoffset, 0, width, height, 1);
2911 Texture *texture =
2912 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002913 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2914 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002915}
2916
2917void Context::texSubImage3D(GLenum target,
2918 GLint level,
2919 GLint xoffset,
2920 GLint yoffset,
2921 GLint zoffset,
2922 GLsizei width,
2923 GLsizei height,
2924 GLsizei depth,
2925 GLenum format,
2926 GLenum type,
2927 const GLvoid *pixels)
2928{
2929 // Zero sized uploads are valid but no-ops
2930 if (width == 0 || height == 0 || depth == 0)
2931 {
2932 return;
2933 }
2934
Jamie Madillad9f24e2016-02-12 09:27:24 -05002935 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002936
2937 Box area(xoffset, yoffset, zoffset, width, height, depth);
2938 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002939 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2940 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002941}
2942
2943void Context::compressedTexImage2D(GLenum target,
2944 GLint level,
2945 GLenum internalformat,
2946 GLsizei width,
2947 GLsizei height,
2948 GLint border,
2949 GLsizei imageSize,
2950 const GLvoid *data)
2951{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002952 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002953
2954 Extents size(width, height, 1);
2955 Texture *texture =
2956 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002957 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002958 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002959 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002960}
2961
2962void Context::compressedTexImage3D(GLenum target,
2963 GLint level,
2964 GLenum internalformat,
2965 GLsizei width,
2966 GLsizei height,
2967 GLsizei depth,
2968 GLint border,
2969 GLsizei imageSize,
2970 const GLvoid *data)
2971{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002972 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002973
2974 Extents size(width, height, depth);
2975 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002976 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002977 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002978 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002979}
2980
2981void Context::compressedTexSubImage2D(GLenum target,
2982 GLint level,
2983 GLint xoffset,
2984 GLint yoffset,
2985 GLsizei width,
2986 GLsizei height,
2987 GLenum format,
2988 GLsizei imageSize,
2989 const GLvoid *data)
2990{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002991 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002992
2993 Box area(xoffset, yoffset, 0, width, height, 1);
2994 Texture *texture =
2995 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002996 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002997 format, imageSize,
2998 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002999}
3000
3001void Context::compressedTexSubImage3D(GLenum target,
3002 GLint level,
3003 GLint xoffset,
3004 GLint yoffset,
3005 GLint zoffset,
3006 GLsizei width,
3007 GLsizei height,
3008 GLsizei depth,
3009 GLenum format,
3010 GLsizei imageSize,
3011 const GLvoid *data)
3012{
3013 // Zero sized uploads are valid but no-ops
3014 if (width == 0 || height == 0)
3015 {
3016 return;
3017 }
3018
Jamie Madillad9f24e2016-02-12 09:27:24 -05003019 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003020
3021 Box area(xoffset, yoffset, zoffset, width, height, depth);
3022 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003023 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003024 format, imageSize,
3025 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003026}
3027
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003028void Context::generateMipmap(GLenum target)
3029{
3030 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003031 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003032}
3033
Geoff Lang97073d12016-04-20 10:42:34 -07003034void Context::copyTextureCHROMIUM(GLuint sourceId,
3035 GLuint destId,
3036 GLint internalFormat,
3037 GLenum destType,
3038 GLboolean unpackFlipY,
3039 GLboolean unpackPremultiplyAlpha,
3040 GLboolean unpackUnmultiplyAlpha)
3041{
3042 syncStateForTexImage();
3043
3044 gl::Texture *sourceTexture = getTexture(sourceId);
3045 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003046 handleError(destTexture->copyTexture(this, internalFormat, destType, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003047 unpackPremultiplyAlpha == GL_TRUE,
3048 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3049}
3050
3051void Context::copySubTextureCHROMIUM(GLuint sourceId,
3052 GLuint destId,
3053 GLint xoffset,
3054 GLint yoffset,
3055 GLint x,
3056 GLint y,
3057 GLsizei width,
3058 GLsizei height,
3059 GLboolean unpackFlipY,
3060 GLboolean unpackPremultiplyAlpha,
3061 GLboolean unpackUnmultiplyAlpha)
3062{
3063 // Zero sized copies are valid but no-ops
3064 if (width == 0 || height == 0)
3065 {
3066 return;
3067 }
3068
3069 syncStateForTexImage();
3070
3071 gl::Texture *sourceTexture = getTexture(sourceId);
3072 gl::Texture *destTexture = getTexture(destId);
3073 Offset offset(xoffset, yoffset, 0);
3074 Rectangle area(x, y, width, height);
Jamie Madill8897afa2017-02-06 17:17:23 -05003075 handleError(destTexture->copySubTexture(this, offset, area, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003076 unpackPremultiplyAlpha == GL_TRUE,
3077 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3078}
3079
Geoff Lang47110bf2016-04-20 11:13:22 -07003080void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3081{
3082 syncStateForTexImage();
3083
3084 gl::Texture *sourceTexture = getTexture(sourceId);
3085 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003086 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003087}
3088
Geoff Lang496c02d2016-10-20 11:38:11 -07003089void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003090{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003091 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003092 ASSERT(buffer);
3093
Geoff Lang496c02d2016-10-20 11:38:11 -07003094 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003095}
3096
3097GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3098{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003099 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003100 ASSERT(buffer);
3101
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003102 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003103 if (error.isError())
3104 {
Jamie Madill437fa652016-05-03 15:13:24 -04003105 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003106 return nullptr;
3107 }
3108
3109 return buffer->getMapPointer();
3110}
3111
3112GLboolean Context::unmapBuffer(GLenum target)
3113{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003114 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003115 ASSERT(buffer);
3116
3117 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003118 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003119 if (error.isError())
3120 {
Jamie Madill437fa652016-05-03 15:13:24 -04003121 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003122 return GL_FALSE;
3123 }
3124
3125 return result;
3126}
3127
3128GLvoid *Context::mapBufferRange(GLenum target,
3129 GLintptr offset,
3130 GLsizeiptr length,
3131 GLbitfield access)
3132{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003133 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003134 ASSERT(buffer);
3135
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003136 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003137 if (error.isError())
3138 {
Jamie Madill437fa652016-05-03 15:13:24 -04003139 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003140 return nullptr;
3141 }
3142
3143 return buffer->getMapPointer();
3144}
3145
3146void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3147{
3148 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3149}
3150
Jamie Madillad9f24e2016-02-12 09:27:24 -05003151void Context::syncStateForReadPixels()
3152{
3153 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3154}
3155
3156void Context::syncStateForTexImage()
3157{
3158 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3159}
3160
3161void Context::syncStateForClear()
3162{
3163 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3164}
3165
3166void Context::syncStateForBlit()
3167{
3168 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3169}
3170
Jamie Madillc20ab272016-06-09 07:20:46 -07003171void Context::activeTexture(GLenum texture)
3172{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003173 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003174}
3175
3176void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3177{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003178 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003179}
3180
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003181void Context::blendEquation(GLenum mode)
3182{
3183 mGLState.setBlendEquation(mode, mode);
3184}
3185
Jamie Madillc20ab272016-06-09 07:20:46 -07003186void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3187{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003188 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003189}
3190
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003191void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3192{
3193 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3194}
3195
Jamie Madillc20ab272016-06-09 07:20:46 -07003196void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3197{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003198 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003199}
3200
3201void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3202{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003203 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003204}
3205
3206void Context::clearDepthf(GLclampf depth)
3207{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003208 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003209}
3210
3211void Context::clearStencil(GLint s)
3212{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003213 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003214}
3215
3216void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3217{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003218 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003219}
3220
3221void Context::cullFace(GLenum mode)
3222{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003223 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003224}
3225
3226void Context::depthFunc(GLenum func)
3227{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003228 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003229}
3230
3231void Context::depthMask(GLboolean flag)
3232{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003233 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003234}
3235
3236void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3237{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003238 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003239}
3240
3241void Context::disable(GLenum cap)
3242{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003243 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003244}
3245
3246void Context::disableVertexAttribArray(GLuint index)
3247{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003248 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003249}
3250
3251void Context::enable(GLenum cap)
3252{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003253 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003254}
3255
3256void Context::enableVertexAttribArray(GLuint index)
3257{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003258 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003259}
3260
3261void Context::frontFace(GLenum mode)
3262{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003263 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003264}
3265
3266void Context::hint(GLenum target, GLenum mode)
3267{
3268 switch (target)
3269 {
3270 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003271 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003272 break;
3273
3274 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003275 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003276 break;
3277
3278 default:
3279 UNREACHABLE();
3280 return;
3281 }
3282}
3283
3284void Context::lineWidth(GLfloat width)
3285{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003286 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003287}
3288
3289void Context::pixelStorei(GLenum pname, GLint param)
3290{
3291 switch (pname)
3292 {
3293 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003294 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003295 break;
3296
3297 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003298 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003299 break;
3300
3301 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003302 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003303 break;
3304
3305 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003306 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003307 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003308 break;
3309
3310 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003311 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003312 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003313 break;
3314
3315 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003316 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003317 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003318 break;
3319
3320 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003321 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003322 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003323 break;
3324
3325 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003326 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003327 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003328 break;
3329
3330 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003331 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003332 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003333 break;
3334
3335 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003336 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003337 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003338 break;
3339
3340 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003341 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003342 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003343 break;
3344
3345 default:
3346 UNREACHABLE();
3347 return;
3348 }
3349}
3350
3351void Context::polygonOffset(GLfloat factor, GLfloat units)
3352{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003353 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003354}
3355
3356void Context::sampleCoverage(GLclampf value, GLboolean invert)
3357{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003358 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003359}
3360
3361void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3362{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003363 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003364}
3365
3366void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3367{
3368 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3369 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003370 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003371 }
3372
3373 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3374 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003375 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003376 }
3377}
3378
3379void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3380{
3381 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3382 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003383 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003384 }
3385
3386 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3387 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003388 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003389 }
3390}
3391
3392void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3393{
3394 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3395 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003396 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003397 }
3398
3399 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3400 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003401 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003402 }
3403}
3404
3405void Context::vertexAttrib1f(GLuint index, GLfloat x)
3406{
3407 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003408 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003409}
3410
3411void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3412{
3413 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003414 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003415}
3416
3417void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3418{
3419 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003420 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003421}
3422
3423void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3424{
3425 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003426 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003427}
3428
3429void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3430{
3431 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003432 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003433}
3434
3435void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3436{
3437 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003438 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003439}
3440
3441void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3442{
3443 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003444 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003445}
3446
3447void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3448{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003449 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003450}
3451
3452void Context::vertexAttribPointer(GLuint index,
3453 GLint size,
3454 GLenum type,
3455 GLboolean normalized,
3456 GLsizei stride,
3457 const GLvoid *ptr)
3458{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3460 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003461}
3462
3463void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3464{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003466}
3467
3468void Context::vertexAttribIPointer(GLuint index,
3469 GLint size,
3470 GLenum type,
3471 GLsizei stride,
3472 const GLvoid *pointer)
3473{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003474 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3475 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003476}
3477
3478void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3479{
3480 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003481 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003482}
3483
3484void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3485{
3486 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003487 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003488}
3489
3490void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3491{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003492 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003493}
3494
3495void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3496{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003497 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003498}
3499
3500void Context::debugMessageControl(GLenum source,
3501 GLenum type,
3502 GLenum severity,
3503 GLsizei count,
3504 const GLuint *ids,
3505 GLboolean enabled)
3506{
3507 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3509 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003510}
3511
3512void Context::debugMessageInsert(GLenum source,
3513 GLenum type,
3514 GLuint id,
3515 GLenum severity,
3516 GLsizei length,
3517 const GLchar *buf)
3518{
3519 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
3523void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3524{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
3528GLuint Context::getDebugMessageLog(GLuint count,
3529 GLsizei bufSize,
3530 GLenum *sources,
3531 GLenum *types,
3532 GLuint *ids,
3533 GLenum *severities,
3534 GLsizei *lengths,
3535 GLchar *messageLog)
3536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3538 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003539}
3540
3541void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3542{
3543 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003544 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003545}
3546
3547void Context::popDebugGroup()
3548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003549 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003550}
3551
Jamie Madill29639852016-09-02 15:00:09 -04003552void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3553{
3554 Buffer *buffer = mGLState.getTargetBuffer(target);
3555 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003556 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003557}
3558
3559void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3560{
3561 if (data == nullptr)
3562 {
3563 return;
3564 }
3565
3566 Buffer *buffer = mGLState.getTargetBuffer(target);
3567 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003568 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003569}
3570
Jamie Madillef300b12016-10-07 15:12:09 -04003571void Context::attachShader(GLuint program, GLuint shader)
3572{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003573 auto programObject = mState.mShaderPrograms->getProgram(program);
3574 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003575 ASSERT(programObject && shaderObject);
3576 programObject->attachShader(shaderObject);
3577}
3578
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003579const Workarounds &Context::getWorkarounds() const
3580{
3581 return mWorkarounds;
3582}
3583
Jamie Madillb0817d12016-11-01 15:48:31 -04003584void Context::copyBufferSubData(GLenum readTarget,
3585 GLenum writeTarget,
3586 GLintptr readOffset,
3587 GLintptr writeOffset,
3588 GLsizeiptr size)
3589{
3590 // if size is zero, the copy is a successful no-op
3591 if (size == 0)
3592 {
3593 return;
3594 }
3595
3596 // TODO(jmadill): cache these.
3597 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3598 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3599
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003600 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003601}
3602
Jamie Madill01a80ee2016-11-07 12:06:18 -05003603void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3604{
3605 Program *programObject = getProgram(program);
3606 // TODO(jmadill): Re-use this from the validation if possible.
3607 ASSERT(programObject);
3608 programObject->bindAttributeLocation(index, name);
3609}
3610
3611void Context::bindBuffer(GLenum target, GLuint buffer)
3612{
3613 switch (target)
3614 {
3615 case GL_ARRAY_BUFFER:
3616 bindArrayBuffer(buffer);
3617 break;
3618 case GL_ELEMENT_ARRAY_BUFFER:
3619 bindElementArrayBuffer(buffer);
3620 break;
3621 case GL_COPY_READ_BUFFER:
3622 bindCopyReadBuffer(buffer);
3623 break;
3624 case GL_COPY_WRITE_BUFFER:
3625 bindCopyWriteBuffer(buffer);
3626 break;
3627 case GL_PIXEL_PACK_BUFFER:
3628 bindPixelPackBuffer(buffer);
3629 break;
3630 case GL_PIXEL_UNPACK_BUFFER:
3631 bindPixelUnpackBuffer(buffer);
3632 break;
3633 case GL_UNIFORM_BUFFER:
3634 bindGenericUniformBuffer(buffer);
3635 break;
3636 case GL_TRANSFORM_FEEDBACK_BUFFER:
3637 bindGenericTransformFeedbackBuffer(buffer);
3638 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003639 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003640 if (buffer != 0)
3641 {
3642 // Binding buffers to this binding point is not implemented yet.
3643 UNIMPLEMENTED();
3644 }
Geoff Lang3b573612016-10-31 14:08:10 -04003645 break;
3646 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003647 if (buffer != 0)
3648 {
3649 // Binding buffers to this binding point is not implemented yet.
3650 UNIMPLEMENTED();
3651 }
Geoff Lang3b573612016-10-31 14:08:10 -04003652 break;
3653 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003654 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003655 break;
3656 case GL_DISPATCH_INDIRECT_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;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003663
3664 default:
3665 UNREACHABLE();
3666 break;
3667 }
3668}
3669
3670void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3671{
3672 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3673 {
3674 bindReadFramebuffer(framebuffer);
3675 }
3676
3677 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3678 {
3679 bindDrawFramebuffer(framebuffer);
3680 }
3681}
3682
3683void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3684{
3685 ASSERT(target == GL_RENDERBUFFER);
3686 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003687 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003688 mGLState.setRenderbufferBinding(object);
3689}
3690
JiangYizhoubddc46b2016-12-09 09:50:51 +08003691void Context::texStorage2DMultisample(GLenum target,
3692 GLsizei samples,
3693 GLenum internalformat,
3694 GLsizei width,
3695 GLsizei height,
3696 GLboolean fixedsamplelocations)
3697{
3698 Extents size(width, height, 1);
3699 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003700 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003701 fixedsamplelocations));
3702}
3703
3704void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3705{
3706 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3707 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3708
3709 switch (pname)
3710 {
3711 case GL_SAMPLE_POSITION:
3712 handleError(framebuffer->getSamplePosition(index, val));
3713 break;
3714 default:
3715 UNREACHABLE();
3716 }
3717}
3718
Jamie Madille8fb6402017-02-14 17:56:40 -05003719void Context::renderbufferStorage(GLenum target,
3720 GLenum internalformat,
3721 GLsizei width,
3722 GLsizei height)
3723{
3724 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
3725 handleError(renderbuffer->setStorage(internalformat, width, height));
3726}
3727
3728void Context::renderbufferStorageMultisample(GLenum target,
3729 GLsizei samples,
3730 GLenum internalformat,
3731 GLsizei width,
3732 GLsizei height)
3733{
3734
3735 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
3736 handleError(renderbuffer->setStorageMultisample(samples, internalformat, width, height));
3737}
3738
Jamie Madillc29968b2016-01-20 11:17:23 -05003739} // namespace gl