blob: 0be5491a45a85188da4c897ad6c71d89a828fa03 [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 Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050021#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050022#include "libANGLE/Display.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>
Sami Väisänend59ca052016-06-21 16:10:00 +030048std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
49 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
68std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
69 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,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500239 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300240
Geoff Langeb66a6e2016-10-31 13:06:12 -0400241 : ValidationContext(GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700242 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500243 mCaps,
244 mTextureCaps,
245 mExtensions,
246 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500247 mLimitations,
Jamie Madill01a80ee2016-11-07 12:06:18 -0500248 mFramebufferMap,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500249 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700250 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500251 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400252 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500253 mClientType(EGL_OPENGL_ES_API),
254 mHasBeenCurrent(false),
255 mContextLost(false),
256 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700257 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500258 mResetStrategy(GetResetStrategy(attribs)),
259 mRobustAccess(GetRobustAccess(attribs)),
260 mCurrentSurface(nullptr),
261 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000262{
Geoff Lang077f20a2016-11-01 10:08:02 -0400263 if (mRobustAccess)
264 {
265 UNIMPLEMENTED();
266 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000267
Geoff Langc287ea62016-09-16 14:46:51 -0400268 initCaps(GetWebGLContext(attribs));
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700269 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400270
Geoff Langeb66a6e2016-10-31 13:06:12 -0400271 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400272 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100273
Shannon Woods53a94a82014-06-24 15:20:36 -0400274 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400275
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400276 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277 {
278 mResourceManager = shareContext->mResourceManager;
279 mResourceManager->addRef();
280 }
281 else
282 {
Jamie Madill901b3792016-05-26 09:20:40 -0400283 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000284 }
285
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700286 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400287
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000288 // [OpenGL ES 2.0.24] section 3.7 page 83:
289 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
290 // and cube map texture state vectors respectively associated with them.
291 // In order that access to these initial textures not be lost, they are treated as texture
292 // objects all of whose names are 0.
293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500298 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400299
Geoff Langeb66a6e2016-10-31 13:06:12 -0400300 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400301 {
302 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500304 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400305
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500307 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308 }
Geoff Lang3b573612016-10-31 14:08:10 -0400309 if (getClientVersion() >= Version(3, 1))
310 {
311 Texture *zeroTexture2DMultisample =
312 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
313 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
314 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000315
Ian Ewellbda75592016-04-18 17:25:54 -0400316 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
317 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400318 Texture *zeroTextureExternal =
319 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400320 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
321 }
322
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700323 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500324
Jamie Madill57a89722013-07-02 11:57:03 -0400325 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000326 bindArrayBuffer(0);
327 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400328
Jamie Madill01a80ee2016-11-07 12:06:18 -0500329 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000330
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000331 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500332 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000333 {
334 bindIndexedUniformBuffer(0, i, 0, -1);
335 }
336
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000337 bindCopyReadBuffer(0);
338 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000339 bindPixelPackBuffer(0);
340 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000341
Geoff Langeb66a6e2016-10-31 13:06:12 -0400342 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400343 {
344 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
345 // In the initial state, a default transform feedback object is bound and treated as
346 // a transform feedback object with a name of zero. That object is bound any time
347 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400348 bindTransformFeedback(0);
349 }
Geoff Langc8058452014-02-03 12:04:11 -0500350
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700351 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500352
353 // Initialize dirty bit masks
354 // TODO(jmadill): additional ES3 state
355 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
356 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
357 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
358 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
359 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
360 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400361 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500362 // No dirty objects.
363
364 // Readpixels uses the pack state and read FBO
365 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
366 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
367 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
368 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
369 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400370 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500371 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
372
373 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
374 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
375 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
376 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
377 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
378 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
379 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
380 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
381 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
382 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
383 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
384 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
385
386 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
387 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700388 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500389 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
390 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400391
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400392 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000393}
394
395Context::~Context()
396{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700397 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000398
Corentin Wallez37c39792015-08-20 14:19:46 -0400399 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000400 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400401 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400402 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400403 {
404 SafeDelete(framebuffer.second);
405 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000406 }
407
Corentin Wallez80b24112015-08-25 16:41:57 -0400408 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000409 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000411 }
412
Corentin Wallez80b24112015-08-25 16:41:57 -0400413 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000414 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400415 if (query.second != nullptr)
416 {
417 query.second->release();
418 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000419 }
420
Corentin Wallez80b24112015-08-25 16:41:57 -0400421 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400422 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400423 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400424 }
425
Corentin Wallez80b24112015-08-25 16:41:57 -0400426 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500427 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500428 if (transformFeedback.second != nullptr)
429 {
430 transformFeedback.second->release();
431 }
Geoff Langc8058452014-02-03 12:04:11 -0500432 }
433
Jamie Madilldedd7b92014-11-05 16:30:36 -0500434 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400435 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500436 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400437 }
438 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000439
Corentin Wallez51706ea2015-08-07 14:39:22 -0400440 if (mCurrentSurface != nullptr)
441 {
442 releaseSurface();
443 }
444
Jamie Madill1e9ae072014-11-06 15:27:21 -0500445 if (mResourceManager)
446 {
447 mResourceManager->release();
448 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500449
450 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000451}
452
daniel@transgaming.comad629872012-11-28 19:32:06 +0000453void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000454{
Jamie Madill77a72f62015-04-14 11:18:32 -0400455 ASSERT(surface != nullptr);
456
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000457 if (!mHasBeenCurrent)
458 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000459 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400460 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000461
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700462 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
463 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000464
465 mHasBeenCurrent = true;
466 }
467
Jamie Madill1b94d432015-08-07 13:23:23 -0400468 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700469 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400470
Corentin Wallez51706ea2015-08-07 14:39:22 -0400471 if (mCurrentSurface)
472 {
473 releaseSurface();
474 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000475 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400476 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000477
Corentin Wallez37c39792015-08-20 14:19:46 -0400478 // Update default framebuffer, the binding of the previous default
479 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400480 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400481 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700482 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400483 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700484 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400485 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700486 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400487 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700488 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400489 }
490 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400491 }
Ian Ewell292f0052016-02-04 10:37:32 -0500492
493 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700494 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000495}
496
Jamie Madill77a72f62015-04-14 11:18:32 -0400497void Context::releaseSurface()
498{
Corentin Wallez37c39792015-08-20 14:19:46 -0400499 ASSERT(mCurrentSurface != nullptr);
500
501 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400502 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400503 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700504 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400505 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700506 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400507 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700508 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400509 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700510 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400511 }
512 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400513 }
514
Corentin Wallez51706ea2015-08-07 14:39:22 -0400515 mCurrentSurface->setIsCurrent(false);
516 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400517}
518
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000519GLuint Context::createBuffer()
520{
521 return mResourceManager->createBuffer();
522}
523
524GLuint Context::createProgram()
525{
Jamie Madill901b3792016-05-26 09:20:40 -0400526 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000527}
528
529GLuint Context::createShader(GLenum type)
530{
Jamie Madill901b3792016-05-26 09:20:40 -0400531 return mResourceManager->createShader(mImplementation.get(),
532 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000533}
534
535GLuint Context::createTexture()
536{
537 return mResourceManager->createTexture();
538}
539
540GLuint Context::createRenderbuffer()
541{
542 return mResourceManager->createRenderbuffer();
543}
544
Geoff Lang882033e2014-09-30 11:26:07 -0400545GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400546{
Jamie Madill901b3792016-05-26 09:20:40 -0400547 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400548
Cooper Partind8e62a32015-01-29 15:21:25 -0800549 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400550}
551
Sami Väisänene45e53b2016-05-25 10:36:04 +0300552GLuint Context::createPaths(GLsizei range)
553{
554 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
555 if (resultOrError.isError())
556 {
557 handleError(resultOrError.getError());
558 return 0;
559 }
560 return resultOrError.getResult();
561}
562
Jamie Madill57a89722013-07-02 11:57:03 -0400563GLuint Context::createVertexArray()
564{
Geoff Lang36167ab2015-12-07 10:27:14 -0500565 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
566 mVertexArrayMap[vertexArray] = nullptr;
567 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400568}
569
Jamie Madilldc356042013-07-19 16:36:57 -0400570GLuint Context::createSampler()
571{
572 return mResourceManager->createSampler();
573}
574
Geoff Langc8058452014-02-03 12:04:11 -0500575GLuint Context::createTransformFeedback()
576{
Geoff Lang36167ab2015-12-07 10:27:14 -0500577 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
578 mTransformFeedbackMap[transformFeedback] = nullptr;
579 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500580}
581
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000582// Returns an unused framebuffer name
583GLuint Context::createFramebuffer()
584{
585 GLuint handle = mFramebufferHandleAllocator.allocate();
586
587 mFramebufferMap[handle] = NULL;
588
589 return handle;
590}
591
Jamie Madill33dc8432013-07-26 11:55:05 -0400592GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000593{
Jamie Madill33dc8432013-07-26 11:55:05 -0400594 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400596 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597
598 return handle;
599}
600
601// Returns an unused query name
602GLuint Context::createQuery()
603{
604 GLuint handle = mQueryHandleAllocator.allocate();
605
606 mQueryMap[handle] = NULL;
607
608 return handle;
609}
610
611void Context::deleteBuffer(GLuint buffer)
612{
613 if (mResourceManager->getBuffer(buffer))
614 {
615 detachBuffer(buffer);
616 }
Jamie Madill893ab082014-05-16 16:56:10 -0400617
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000618 mResourceManager->deleteBuffer(buffer);
619}
620
621void Context::deleteShader(GLuint shader)
622{
623 mResourceManager->deleteShader(shader);
624}
625
626void Context::deleteProgram(GLuint program)
627{
628 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629}
630
631void Context::deleteTexture(GLuint texture)
632{
633 if (mResourceManager->getTexture(texture))
634 {
635 detachTexture(texture);
636 }
637
638 mResourceManager->deleteTexture(texture);
639}
640
641void Context::deleteRenderbuffer(GLuint renderbuffer)
642{
643 if (mResourceManager->getRenderbuffer(renderbuffer))
644 {
645 detachRenderbuffer(renderbuffer);
646 }
Jamie Madill893ab082014-05-16 16:56:10 -0400647
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000648 mResourceManager->deleteRenderbuffer(renderbuffer);
649}
650
Jamie Madillcd055f82013-07-26 11:55:15 -0400651void Context::deleteFenceSync(GLsync fenceSync)
652{
653 // The spec specifies the underlying Fence object is not deleted until all current
654 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
655 // and since our API is currently designed for being called from a single thread, we can delete
656 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700657 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400658}
659
Sami Väisänene45e53b2016-05-25 10:36:04 +0300660void Context::deletePaths(GLuint first, GLsizei range)
661{
662 mResourceManager->deletePaths(first, range);
663}
664
665bool Context::hasPathData(GLuint path) const
666{
667 const auto *pathObj = mResourceManager->getPath(path);
668 if (pathObj == nullptr)
669 return false;
670
671 return pathObj->hasPathData();
672}
673
674bool Context::hasPath(GLuint path) const
675{
676 return mResourceManager->hasPath(path);
677}
678
679void Context::setPathCommands(GLuint path,
680 GLsizei numCommands,
681 const GLubyte *commands,
682 GLsizei numCoords,
683 GLenum coordType,
684 const void *coords)
685{
686 auto *pathObject = mResourceManager->getPath(path);
687
688 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
689}
690
691void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
692{
693 auto *pathObj = mResourceManager->getPath(path);
694
695 switch (pname)
696 {
697 case GL_PATH_STROKE_WIDTH_CHROMIUM:
698 pathObj->setStrokeWidth(value);
699 break;
700 case GL_PATH_END_CAPS_CHROMIUM:
701 pathObj->setEndCaps(static_cast<GLenum>(value));
702 break;
703 case GL_PATH_JOIN_STYLE_CHROMIUM:
704 pathObj->setJoinStyle(static_cast<GLenum>(value));
705 break;
706 case GL_PATH_MITER_LIMIT_CHROMIUM:
707 pathObj->setMiterLimit(value);
708 break;
709 case GL_PATH_STROKE_BOUND_CHROMIUM:
710 pathObj->setStrokeBound(value);
711 break;
712 default:
713 UNREACHABLE();
714 break;
715 }
716}
717
718void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
719{
720 const auto *pathObj = mResourceManager->getPath(path);
721
722 switch (pname)
723 {
724 case GL_PATH_STROKE_WIDTH_CHROMIUM:
725 *value = pathObj->getStrokeWidth();
726 break;
727 case GL_PATH_END_CAPS_CHROMIUM:
728 *value = static_cast<GLfloat>(pathObj->getEndCaps());
729 break;
730 case GL_PATH_JOIN_STYLE_CHROMIUM:
731 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
732 break;
733 case GL_PATH_MITER_LIMIT_CHROMIUM:
734 *value = pathObj->getMiterLimit();
735 break;
736 case GL_PATH_STROKE_BOUND_CHROMIUM:
737 *value = pathObj->getStrokeBound();
738 break;
739 default:
740 UNREACHABLE();
741 break;
742 }
743}
744
745void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
746{
747 mGLState.setPathStencilFunc(func, ref, mask);
748}
749
Jamie Madill57a89722013-07-02 11:57:03 -0400750void Context::deleteVertexArray(GLuint vertexArray)
751{
Geoff Lang36167ab2015-12-07 10:27:14 -0500752 auto iter = mVertexArrayMap.find(vertexArray);
753 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000754 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500755 VertexArray *vertexArrayObject = iter->second;
756 if (vertexArrayObject != nullptr)
757 {
758 detachVertexArray(vertexArray);
759 delete vertexArrayObject;
760 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000761
Geoff Lang36167ab2015-12-07 10:27:14 -0500762 mVertexArrayMap.erase(iter);
763 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400764 }
765}
766
Jamie Madilldc356042013-07-19 16:36:57 -0400767void Context::deleteSampler(GLuint sampler)
768{
769 if (mResourceManager->getSampler(sampler))
770 {
771 detachSampler(sampler);
772 }
773
774 mResourceManager->deleteSampler(sampler);
775}
776
Geoff Langc8058452014-02-03 12:04:11 -0500777void Context::deleteTransformFeedback(GLuint transformFeedback)
778{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500779 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500780 if (iter != mTransformFeedbackMap.end())
781 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500782 TransformFeedback *transformFeedbackObject = iter->second;
783 if (transformFeedbackObject != nullptr)
784 {
785 detachTransformFeedback(transformFeedback);
786 transformFeedbackObject->release();
787 }
788
Geoff Lang50b3fe82015-12-08 14:49:12 +0000789 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500790 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500791 }
792}
793
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794void Context::deleteFramebuffer(GLuint framebuffer)
795{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500796 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000797
798 if (framebufferObject != mFramebufferMap.end())
799 {
800 detachFramebuffer(framebuffer);
801
802 mFramebufferHandleAllocator.release(framebufferObject->first);
803 delete framebufferObject->second;
804 mFramebufferMap.erase(framebufferObject);
805 }
806}
807
Jamie Madill33dc8432013-07-26 11:55:05 -0400808void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000809{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500810 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000811
Jamie Madill33dc8432013-07-26 11:55:05 -0400812 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400814 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400816 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000817 }
818}
819
820void Context::deleteQuery(GLuint query)
821{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500822 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000823 if (queryObject != mQueryMap.end())
824 {
825 mQueryHandleAllocator.release(queryObject->first);
826 if (queryObject->second)
827 {
828 queryObject->second->release();
829 }
830 mQueryMap.erase(queryObject);
831 }
832}
833
Geoff Lang70d0f492015-12-10 17:45:46 -0500834Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835{
836 return mResourceManager->getBuffer(handle);
837}
838
Jamie Madill570f7c82014-07-03 10:38:54 -0400839Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840{
841 return mResourceManager->getTexture(handle);
842}
843
Geoff Lang70d0f492015-12-10 17:45:46 -0500844Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000845{
846 return mResourceManager->getRenderbuffer(handle);
847}
848
Jamie Madillcd055f82013-07-26 11:55:15 -0400849FenceSync *Context::getFenceSync(GLsync handle) const
850{
Minmin Gong794e0002015-04-07 18:31:54 -0700851 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400852}
853
Jamie Madill57a89722013-07-02 11:57:03 -0400854VertexArray *Context::getVertexArray(GLuint handle) const
855{
856 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500857 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400858}
859
Jamie Madilldc356042013-07-19 16:36:57 -0400860Sampler *Context::getSampler(GLuint handle) const
861{
862 return mResourceManager->getSampler(handle);
863}
864
Geoff Langc8058452014-02-03 12:04:11 -0500865TransformFeedback *Context::getTransformFeedback(GLuint handle) const
866{
Geoff Lang36167ab2015-12-07 10:27:14 -0500867 auto iter = mTransformFeedbackMap.find(handle);
868 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500869}
870
Geoff Lang70d0f492015-12-10 17:45:46 -0500871LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
872{
873 switch (identifier)
874 {
875 case GL_BUFFER:
876 return getBuffer(name);
877 case GL_SHADER:
878 return getShader(name);
879 case GL_PROGRAM:
880 return getProgram(name);
881 case GL_VERTEX_ARRAY:
882 return getVertexArray(name);
883 case GL_QUERY:
884 return getQuery(name);
885 case GL_TRANSFORM_FEEDBACK:
886 return getTransformFeedback(name);
887 case GL_SAMPLER:
888 return getSampler(name);
889 case GL_TEXTURE:
890 return getTexture(name);
891 case GL_RENDERBUFFER:
892 return getRenderbuffer(name);
893 case GL_FRAMEBUFFER:
894 return getFramebuffer(name);
895 default:
896 UNREACHABLE();
897 return nullptr;
898 }
899}
900
901LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
902{
903 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
904}
905
Martin Radev9d901792016-07-15 15:58:58 +0300906void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
907{
908 LabeledObject *object = getLabeledObject(identifier, name);
909 ASSERT(object != nullptr);
910
911 std::string labelName = GetObjectLabelFromPointer(length, label);
912 object->setLabel(labelName);
913}
914
915void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
916{
917 LabeledObject *object = getLabeledObjectFromPtr(ptr);
918 ASSERT(object != nullptr);
919
920 std::string labelName = GetObjectLabelFromPointer(length, label);
921 object->setLabel(labelName);
922}
923
924void Context::getObjectLabel(GLenum identifier,
925 GLuint name,
926 GLsizei bufSize,
927 GLsizei *length,
928 GLchar *label) const
929{
930 LabeledObject *object = getLabeledObject(identifier, name);
931 ASSERT(object != nullptr);
932
933 const std::string &objectLabel = object->getLabel();
934 GetObjectLabelBase(objectLabel, bufSize, length, label);
935}
936
937void Context::getObjectPtrLabel(const void *ptr,
938 GLsizei bufSize,
939 GLsizei *length,
940 GLchar *label) const
941{
942 LabeledObject *object = getLabeledObjectFromPtr(ptr);
943 ASSERT(object != nullptr);
944
945 const std::string &objectLabel = object->getLabel();
946 GetObjectLabelBase(objectLabel, bufSize, length, label);
947}
948
Jamie Madilldc356042013-07-19 16:36:57 -0400949bool Context::isSampler(GLuint samplerName) const
950{
951 return mResourceManager->isSampler(samplerName);
952}
953
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500954void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955{
Jamie Madill901b3792016-05-26 09:20:40 -0400956 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700957 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958}
959
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500960void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000961{
Jamie Madill901b3792016-05-26 09:20:40 -0400962 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700963 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000964}
965
Jamie Madilldedd7b92014-11-05 16:30:36 -0500966void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000967{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500968 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000969
Jamie Madilldedd7b92014-11-05 16:30:36 -0500970 if (handle == 0)
971 {
972 texture = mZeroTextures[target].get();
973 }
974 else
975 {
Jamie Madill901b3792016-05-26 09:20:40 -0400976 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500977 }
978
979 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700980 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000981}
982
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500983void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500985 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700986 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987}
988
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500989void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000990{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500991 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700992 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993}
994
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500995void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400996{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500997 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700998 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400999}
1000
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001001void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001002{
Geoff Lang76b10c92014-09-05 16:28:14 -04001003 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001004 Sampler *sampler =
1005 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001006 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001007}
1008
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001009void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001010{
Jamie Madill901b3792016-05-26 09:20:40 -04001011 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001012 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001013}
1014
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001015void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1016 GLuint index,
1017 GLintptr offset,
1018 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001019{
Jamie Madill901b3792016-05-26 09:20:40 -04001020 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001022}
1023
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001025{
Jamie Madill901b3792016-05-26 09:20:40 -04001026 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001028}
1029
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001030void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1031 GLuint index,
1032 GLintptr offset,
1033 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001034{
Jamie Madill901b3792016-05-26 09:20:40 -04001035 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001036 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001037}
1038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001040{
Jamie Madill901b3792016-05-26 09:20:40 -04001041 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001042 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001043}
1044
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001045void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001046{
Jamie Madill901b3792016-05-26 09:20:40 -04001047 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001048 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001049}
1050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001051void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001052{
Jamie Madill901b3792016-05-26 09:20:40 -04001053 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001054 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001055}
1056
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001057void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001058{
Jamie Madill901b3792016-05-26 09:20:40 -04001059 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001060 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001061}
1062
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001063void Context::useProgram(GLuint program)
1064{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001065 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001066}
1067
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001068void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001069{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001070 TransformFeedback *transformFeedback =
1071 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001072 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001073}
1074
Geoff Lang5aad9672014-09-08 11:10:42 -04001075Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001078 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001079
Geoff Lang5aad9672014-09-08 11:10:42 -04001080 // begin query
1081 Error error = queryObject->begin();
1082 if (error.isError())
1083 {
1084 return error;
1085 }
1086
1087 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001088 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001089
Geoff Lang5aad9672014-09-08 11:10:42 -04001090 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091}
1092
Geoff Lang5aad9672014-09-08 11:10:42 -04001093Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001094{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001095 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001096 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001097
Geoff Lang5aad9672014-09-08 11:10:42 -04001098 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001099
Geoff Lang5aad9672014-09-08 11:10:42 -04001100 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001101 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001102
1103 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001104}
1105
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001106Error Context::queryCounter(GLuint id, GLenum target)
1107{
1108 ASSERT(target == GL_TIMESTAMP_EXT);
1109
1110 Query *queryObject = getQuery(id, true, target);
1111 ASSERT(queryObject);
1112
1113 return queryObject->queryCounter();
1114}
1115
1116void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1117{
1118 switch (pname)
1119 {
1120 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001121 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001122 break;
1123 case GL_QUERY_COUNTER_BITS_EXT:
1124 switch (target)
1125 {
1126 case GL_TIME_ELAPSED_EXT:
1127 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1128 break;
1129 case GL_TIMESTAMP_EXT:
1130 params[0] = getExtensions().queryCounterBitsTimestamp;
1131 break;
1132 default:
1133 UNREACHABLE();
1134 params[0] = 0;
1135 break;
1136 }
1137 break;
1138 default:
1139 UNREACHABLE();
1140 return;
1141 }
1142}
1143
Geoff Lang2186c382016-10-14 10:54:54 -04001144void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001145{
Geoff Lang2186c382016-10-14 10:54:54 -04001146 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001147}
1148
Geoff Lang2186c382016-10-14 10:54:54 -04001149void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001150{
Geoff Lang2186c382016-10-14 10:54:54 -04001151 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001152}
1153
Geoff Lang2186c382016-10-14 10:54:54 -04001154void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001155{
Geoff Lang2186c382016-10-14 10:54:54 -04001156 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001157}
1158
Geoff Lang2186c382016-10-14 10:54:54 -04001159void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001160{
Geoff Lang2186c382016-10-14 10:54:54 -04001161 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001162}
1163
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001164Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001166 auto framebufferIt = mFramebufferMap.find(handle);
1167 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001168}
1169
Jamie Madill33dc8432013-07-26 11:55:05 -04001170FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001172 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173
Jamie Madill33dc8432013-07-26 11:55:05 -04001174 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175 {
1176 return NULL;
1177 }
1178 else
1179 {
1180 return fence->second;
1181 }
1182}
1183
1184Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1185{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001186 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187
1188 if (query == mQueryMap.end())
1189 {
1190 return NULL;
1191 }
1192 else
1193 {
1194 if (!query->second && create)
1195 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001196 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197 query->second->addRef();
1198 }
1199 return query->second;
1200 }
1201}
1202
Geoff Lang70d0f492015-12-10 17:45:46 -05001203Query *Context::getQuery(GLuint handle) const
1204{
1205 auto iter = mQueryMap.find(handle);
1206 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1207}
1208
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001209Texture *Context::getTargetTexture(GLenum target) const
1210{
Ian Ewellbda75592016-04-18 17:25:54 -04001211 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001212 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001213}
1214
Geoff Lang76b10c92014-09-05 16:28:14 -04001215Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001217 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218}
1219
Geoff Lang492a7e42014-11-05 13:27:06 -05001220Compiler *Context::getCompiler() const
1221{
1222 return mCompiler;
1223}
1224
Jamie Madill893ab082014-05-16 16:56:10 -04001225void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226{
1227 switch (pname)
1228 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001229 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001230 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001231 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001232 mGLState.getBooleanv(pname, params);
1233 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001234 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235}
1236
Jamie Madill893ab082014-05-16 16:56:10 -04001237void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238{
Shannon Woods53a94a82014-06-24 15:20:36 -04001239 // Queries about context capabilities and maximums are answered by Context.
1240 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241 switch (pname)
1242 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001244 params[0] = mCaps.minAliasedLineWidth;
1245 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246 break;
1247 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001248 params[0] = mCaps.minAliasedPointSize;
1249 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001251 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001252 ASSERT(mExtensions.textureFilterAnisotropic);
1253 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001254 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001255 case GL_MAX_TEXTURE_LOD_BIAS:
1256 *params = mCaps.maxLODBias;
1257 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001258
1259 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1260 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1261 {
1262 ASSERT(mExtensions.pathRendering);
1263 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1264 memcpy(params, m, 16 * sizeof(GLfloat));
1265 }
1266 break;
1267
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001269 mGLState.getFloatv(pname, params);
1270 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272}
1273
Jamie Madill893ab082014-05-16 16:56:10 -04001274void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275{
Shannon Woods53a94a82014-06-24 15:20:36 -04001276 // Queries about context capabilities and maximums are answered by Context.
1277 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001278
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279 switch (pname)
1280 {
Geoff Lang301d1612014-07-09 10:34:37 -04001281 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1282 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1283 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001284 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1285 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1286 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001287 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1288 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1289 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001290 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001291 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1292 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1293 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001294 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001295 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001296 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1297 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1298 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1299 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001300 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1301 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001302 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1303 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001304 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001305 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1306 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1307 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1308 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001309 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001310 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001311 break;
1312 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001313 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001314 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001315 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1316 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001317 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1318 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1319 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001320 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1321 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1322 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001323 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324 case GL_MAX_VIEWPORT_DIMS:
1325 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001326 params[0] = mCaps.maxViewportWidth;
1327 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 }
1329 break;
1330 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001331 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001333 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1334 *params = mResetStrategy;
1335 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001336 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001337 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001338 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001339 case GL_SHADER_BINARY_FORMATS:
1340 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1341 break;
1342 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001343 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001344 break;
1345 case GL_PROGRAM_BINARY_FORMATS:
1346 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001347 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001348 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001349 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001350 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001351
1352 // GL_KHR_debug
1353 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1354 *params = mExtensions.maxDebugMessageLength;
1355 break;
1356 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1357 *params = mExtensions.maxDebugLoggedMessages;
1358 break;
1359 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1360 *params = mExtensions.maxDebugGroupStackDepth;
1361 break;
1362 case GL_MAX_LABEL_LENGTH:
1363 *params = mExtensions.maxLabelLength;
1364 break;
1365
Ian Ewell53f59f42016-01-28 17:36:55 -05001366 // GL_EXT_disjoint_timer_query
1367 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001368 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001369 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001370 case GL_MAX_FRAMEBUFFER_WIDTH:
1371 *params = mCaps.maxFramebufferWidth;
1372 break;
1373 case GL_MAX_FRAMEBUFFER_HEIGHT:
1374 *params = mCaps.maxFramebufferHeight;
1375 break;
1376 case GL_MAX_FRAMEBUFFER_SAMPLES:
1377 *params = mCaps.maxFramebufferSamples;
1378 break;
1379 case GL_MAX_SAMPLE_MASK_WORDS:
1380 *params = mCaps.maxSampleMaskWords;
1381 break;
1382 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1383 *params = mCaps.maxColorTextureSamples;
1384 break;
1385 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1386 *params = mCaps.maxDepthTextureSamples;
1387 break;
1388 case GL_MAX_INTEGER_SAMPLES:
1389 *params = mCaps.maxIntegerSamples;
1390 break;
1391 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1392 *params = mCaps.maxVertexAttribRelativeOffset;
1393 break;
1394 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1395 *params = mCaps.maxVertexAttribBindings;
1396 break;
1397 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1398 *params = mCaps.maxVertexAttribStride;
1399 break;
1400 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1401 *params = mCaps.maxVertexAtomicCounterBuffers;
1402 break;
1403 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1404 *params = mCaps.maxVertexAtomicCounters;
1405 break;
1406 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1407 *params = mCaps.maxVertexImageUniforms;
1408 break;
1409 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1410 *params = mCaps.maxVertexShaderStorageBlocks;
1411 break;
1412 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1413 *params = mCaps.maxFragmentAtomicCounterBuffers;
1414 break;
1415 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1416 *params = mCaps.maxFragmentAtomicCounters;
1417 break;
1418 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1419 *params = mCaps.maxFragmentImageUniforms;
1420 break;
1421 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1422 *params = mCaps.maxFragmentShaderStorageBlocks;
1423 break;
1424 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1425 *params = mCaps.minProgramTextureGatherOffset;
1426 break;
1427 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1428 *params = mCaps.maxProgramTextureGatherOffset;
1429 break;
1430 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1431 *params = mCaps.maxComputeWorkGroupInvocations;
1432 break;
1433 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1434 *params = mCaps.maxComputeUniformBlocks;
1435 break;
1436 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1437 *params = mCaps.maxComputeTextureImageUnits;
1438 break;
1439 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1440 *params = mCaps.maxComputeSharedMemorySize;
1441 break;
1442 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1443 *params = mCaps.maxComputeUniformComponents;
1444 break;
1445 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1446 *params = mCaps.maxComputeAtomicCounterBuffers;
1447 break;
1448 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1449 *params = mCaps.maxComputeAtomicCounters;
1450 break;
1451 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1452 *params = mCaps.maxComputeImageUniforms;
1453 break;
1454 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1455 *params = mCaps.maxCombinedComputeUniformComponents;
1456 break;
1457 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1458 *params = mCaps.maxComputeShaderStorageBlocks;
1459 break;
1460 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1461 *params = mCaps.maxCombinedShaderOutputResources;
1462 break;
1463 case GL_MAX_UNIFORM_LOCATIONS:
1464 *params = mCaps.maxUniformLocations;
1465 break;
1466 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1467 *params = mCaps.maxAtomicCounterBufferBindings;
1468 break;
1469 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1470 *params = mCaps.maxAtomicCounterBufferSize;
1471 break;
1472 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1473 *params = mCaps.maxCombinedAtomicCounterBuffers;
1474 break;
1475 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1476 *params = mCaps.maxCombinedAtomicCounters;
1477 break;
1478 case GL_MAX_IMAGE_UNITS:
1479 *params = mCaps.maxImageUnits;
1480 break;
1481 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1482 *params = mCaps.maxCombinedImageUniforms;
1483 break;
1484 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1485 *params = mCaps.maxShaderStorageBufferBindings;
1486 break;
1487 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1488 *params = mCaps.maxCombinedShaderStorageBlocks;
1489 break;
1490 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1491 *params = mCaps.shaderStorageBufferOffsetAlignment;
1492 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001493 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001494 mGLState.getIntegerv(mState, pname, params);
1495 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001496 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001497}
1498
Jamie Madill893ab082014-05-16 16:56:10 -04001499void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001500{
Shannon Woods53a94a82014-06-24 15:20:36 -04001501 // Queries about context capabilities and maximums are answered by Context.
1502 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001503 switch (pname)
1504 {
1505 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001506 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001507 break;
1508 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001509 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001510 break;
1511 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001512 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001513 break;
1514 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001515 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001516 break;
1517 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001518 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001519 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001520
1521 // GL_EXT_disjoint_timer_query
1522 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001523 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001524 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001525
1526 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1527 *params = mCaps.maxShaderStorageBlockSize;
1528 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001529 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001530 UNREACHABLE();
1531 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001532 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001533}
1534
Geoff Lang70d0f492015-12-10 17:45:46 -05001535void Context::getPointerv(GLenum pname, void **params) const
1536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001537 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001538}
1539
Martin Radev66fb8202016-07-28 11:45:20 +03001540void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001541{
Shannon Woods53a94a82014-06-24 15:20:36 -04001542 // Queries about context capabilities and maximums are answered by Context.
1543 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001544
1545 GLenum nativeType;
1546 unsigned int numParams;
1547 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1548 ASSERT(queryStatus);
1549
1550 if (nativeType == GL_INT)
1551 {
1552 switch (target)
1553 {
1554 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1555 ASSERT(index < 3u);
1556 *data = mCaps.maxComputeWorkGroupCount[index];
1557 break;
1558 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1559 ASSERT(index < 3u);
1560 *data = mCaps.maxComputeWorkGroupSize[index];
1561 break;
1562 default:
1563 mGLState.getIntegeri_v(target, index, data);
1564 }
1565 }
1566 else
1567 {
1568 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1569 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001570}
1571
Martin Radev66fb8202016-07-28 11:45:20 +03001572void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001573{
Shannon Woods53a94a82014-06-24 15:20:36 -04001574 // Queries about context capabilities and maximums are answered by Context.
1575 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001576
1577 GLenum nativeType;
1578 unsigned int numParams;
1579 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1580 ASSERT(queryStatus);
1581
1582 if (nativeType == GL_INT_64_ANGLEX)
1583 {
1584 mGLState.getInteger64i_v(target, index, data);
1585 }
1586 else
1587 {
1588 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1589 }
1590}
1591
1592void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1593{
1594 // Queries about context capabilities and maximums are answered by Context.
1595 // Queries about current GL state values are answered by State.
1596
1597 GLenum nativeType;
1598 unsigned int numParams;
1599 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1600 ASSERT(queryStatus);
1601
1602 if (nativeType == GL_BOOL)
1603 {
1604 mGLState.getBooleani_v(target, index, data);
1605 }
1606 else
1607 {
1608 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1609 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001610}
1611
Geoff Langf6db0982015-08-25 13:04:00 -04001612Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001613{
Jamie Madill1b94d432015-08-07 13:23:23 -04001614 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001615 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001616 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001617
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001618 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001619}
1620
Geoff Langf6db0982015-08-25 13:04:00 -04001621Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1622{
1623 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001624 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001625 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001626
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001627 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001628}
1629
1630Error Context::drawElements(GLenum mode,
1631 GLsizei count,
1632 GLenum type,
1633 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001634 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001635{
Jamie Madill1b94d432015-08-07 13:23:23 -04001636 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001637 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001638}
1639
1640Error Context::drawElementsInstanced(GLenum mode,
1641 GLsizei count,
1642 GLenum type,
1643 const GLvoid *indices,
1644 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001645 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001646{
1647 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001648 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1649 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001650}
1651
1652Error Context::drawRangeElements(GLenum mode,
1653 GLuint start,
1654 GLuint end,
1655 GLsizei count,
1656 GLenum type,
1657 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001658 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001659{
1660 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001661 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001662}
1663
Geoff Lang129753a2015-01-09 16:52:09 -05001664Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001665{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001666 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001667}
1668
1669Error Context::finish()
1670{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001671 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001672}
1673
Austin Kinross6ee1e782015-05-29 17:05:37 -07001674void Context::insertEventMarker(GLsizei length, const char *marker)
1675{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001676 ASSERT(mImplementation);
1677 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001678}
1679
1680void Context::pushGroupMarker(GLsizei length, const char *marker)
1681{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001682 ASSERT(mImplementation);
1683 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001684}
1685
1686void Context::popGroupMarker()
1687{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001688 ASSERT(mImplementation);
1689 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001690}
1691
Geoff Langd8605522016-04-13 10:19:12 -04001692void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1693{
1694 Program *programObject = getProgram(program);
1695 ASSERT(programObject);
1696
1697 programObject->bindUniformLocation(location, name);
1698}
1699
Sami Väisänena797e062016-05-12 15:23:40 +03001700void Context::setCoverageModulation(GLenum components)
1701{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001702 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001703}
1704
Sami Väisänene45e53b2016-05-25 10:36:04 +03001705void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1706{
1707 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1708}
1709
1710void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1711{
1712 GLfloat I[16];
1713 angle::Matrix<GLfloat>::setToIdentity(I);
1714
1715 mGLState.loadPathRenderingMatrix(matrixMode, I);
1716}
1717
1718void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1719{
1720 const auto *pathObj = mResourceManager->getPath(path);
1721 if (!pathObj)
1722 return;
1723
1724 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1725 syncRendererState();
1726
1727 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1728}
1729
1730void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1731{
1732 const auto *pathObj = mResourceManager->getPath(path);
1733 if (!pathObj)
1734 return;
1735
1736 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1737 syncRendererState();
1738
1739 mImplementation->stencilStrokePath(pathObj, reference, mask);
1740}
1741
1742void Context::coverFillPath(GLuint path, GLenum coverMode)
1743{
1744 const auto *pathObj = mResourceManager->getPath(path);
1745 if (!pathObj)
1746 return;
1747
1748 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1749 syncRendererState();
1750
1751 mImplementation->coverFillPath(pathObj, coverMode);
1752}
1753
1754void Context::coverStrokePath(GLuint path, GLenum coverMode)
1755{
1756 const auto *pathObj = mResourceManager->getPath(path);
1757 if (!pathObj)
1758 return;
1759
1760 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1761 syncRendererState();
1762
1763 mImplementation->coverStrokePath(pathObj, coverMode);
1764}
1765
1766void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1767{
1768 const auto *pathObj = mResourceManager->getPath(path);
1769 if (!pathObj)
1770 return;
1771
1772 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1773 syncRendererState();
1774
1775 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1776}
1777
1778void Context::stencilThenCoverStrokePath(GLuint path,
1779 GLint reference,
1780 GLuint mask,
1781 GLenum coverMode)
1782{
1783 const auto *pathObj = mResourceManager->getPath(path);
1784 if (!pathObj)
1785 return;
1786
1787 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1788 syncRendererState();
1789
1790 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1791}
1792
Sami Väisänend59ca052016-06-21 16:10:00 +03001793void Context::coverFillPathInstanced(GLsizei numPaths,
1794 GLenum pathNameType,
1795 const void *paths,
1796 GLuint pathBase,
1797 GLenum coverMode,
1798 GLenum transformType,
1799 const GLfloat *transformValues)
1800{
1801 const auto &pathObjects =
1802 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1803
1804 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1805 syncRendererState();
1806
1807 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1808}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001809
Sami Väisänend59ca052016-06-21 16:10:00 +03001810void Context::coverStrokePathInstanced(GLsizei numPaths,
1811 GLenum pathNameType,
1812 const void *paths,
1813 GLuint pathBase,
1814 GLenum coverMode,
1815 GLenum transformType,
1816 const GLfloat *transformValues)
1817{
1818 const auto &pathObjects =
1819 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1820
1821 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1822 syncRendererState();
1823
1824 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1825 transformValues);
1826}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001827
Sami Väisänend59ca052016-06-21 16:10:00 +03001828void Context::stencilFillPathInstanced(GLsizei numPaths,
1829 GLenum pathNameType,
1830 const void *paths,
1831 GLuint pathBase,
1832 GLenum fillMode,
1833 GLuint mask,
1834 GLenum transformType,
1835 const GLfloat *transformValues)
1836{
1837 const auto &pathObjects =
1838 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1839
1840 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1841 syncRendererState();
1842
1843 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1844 transformValues);
1845}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001846
Sami Väisänend59ca052016-06-21 16:10:00 +03001847void Context::stencilStrokePathInstanced(GLsizei numPaths,
1848 GLenum pathNameType,
1849 const void *paths,
1850 GLuint pathBase,
1851 GLint reference,
1852 GLuint mask,
1853 GLenum transformType,
1854 const GLfloat *transformValues)
1855{
1856 const auto &pathObjects =
1857 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1858
1859 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1860 syncRendererState();
1861
1862 mImplementation->stencilStrokePathInstanced(pathObjects, reference, 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::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1867 GLenum pathNameType,
1868 const void *paths,
1869 GLuint pathBase,
1870 GLenum fillMode,
1871 GLuint mask,
1872 GLenum coverMode,
1873 GLenum transformType,
1874 const GLfloat *transformValues)
1875{
1876 const auto &pathObjects =
1877 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1878
1879 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1880 syncRendererState();
1881
1882 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1883 transformType, transformValues);
1884}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001885
Sami Väisänend59ca052016-06-21 16:10:00 +03001886void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1887 GLenum pathNameType,
1888 const void *paths,
1889 GLuint pathBase,
1890 GLint reference,
1891 GLuint mask,
1892 GLenum coverMode,
1893 GLenum transformType,
1894 const GLfloat *transformValues)
1895{
1896 const auto &pathObjects =
1897 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1898
1899 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1900 syncRendererState();
1901
1902 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1903 transformType, transformValues);
1904}
1905
Sami Väisänen46eaa942016-06-29 10:26:37 +03001906void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1907{
1908 auto *programObject = getProgram(program);
1909
1910 programObject->bindFragmentInputLocation(location, name);
1911}
1912
1913void Context::programPathFragmentInputGen(GLuint program,
1914 GLint location,
1915 GLenum genMode,
1916 GLint components,
1917 const GLfloat *coeffs)
1918{
1919 auto *programObject = getProgram(program);
1920
1921 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1922}
1923
Jamie Madill437fa652016-05-03 15:13:24 -04001924void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001925{
Geoff Langda5777c2014-07-11 09:52:58 -04001926 if (error.isError())
1927 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001928 GLenum code = error.getCode();
1929 mErrors.insert(code);
1930 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1931 {
1932 markContextLost();
1933 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001934
1935 if (!error.getMessage().empty())
1936 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001937 auto *debug = &mGLState.getDebug();
1938 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1939 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001940 }
Geoff Langda5777c2014-07-11 09:52:58 -04001941 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001942}
1943
1944// Get one of the recorded errors and clear its flag, if any.
1945// [OpenGL ES 2.0.24] section 2.5 page 13.
1946GLenum Context::getError()
1947{
Geoff Langda5777c2014-07-11 09:52:58 -04001948 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001949 {
Geoff Langda5777c2014-07-11 09:52:58 -04001950 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001951 }
Geoff Langda5777c2014-07-11 09:52:58 -04001952 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001953 {
Geoff Langda5777c2014-07-11 09:52:58 -04001954 GLenum error = *mErrors.begin();
1955 mErrors.erase(mErrors.begin());
1956 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001957 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001958}
1959
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001960// NOTE: this function should not assume that this context is current!
1961void Context::markContextLost()
1962{
1963 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001964 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001965 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001966 mContextLostForced = true;
1967 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001968 mContextLost = true;
1969}
1970
1971bool Context::isContextLost()
1972{
1973 return mContextLost;
1974}
1975
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001976GLenum Context::getResetStatus()
1977{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001978 // Even if the application doesn't want to know about resets, we want to know
1979 // as it will allow us to skip all the calls.
1980 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001981 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001982 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001983 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001984 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001985 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001986
1987 // EXT_robustness, section 2.6: If the reset notification behavior is
1988 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1989 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1990 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001991 }
1992
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001993 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1994 // status should be returned at least once, and GL_NO_ERROR should be returned
1995 // once the device has finished resetting.
1996 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001997 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001998 ASSERT(mResetStatus == GL_NO_ERROR);
1999 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002000
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002001 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002002 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002003 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002004 }
2005 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002006 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002007 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002008 // If markContextLost was used to mark the context lost then
2009 // assume that is not recoverable, and continue to report the
2010 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002011 mResetStatus = mImplementation->getResetStatus();
2012 }
Jamie Madill893ab082014-05-16 16:56:10 -04002013
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002014 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002015}
2016
2017bool Context::isResetNotificationEnabled()
2018{
2019 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2020}
2021
Corentin Walleze3b10e82015-05-20 11:06:25 -04002022const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002023{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002024 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002025}
2026
2027EGLenum Context::getClientType() const
2028{
2029 return mClientType;
2030}
2031
2032EGLenum Context::getRenderBuffer() const
2033{
Corentin Wallez37c39792015-08-20 14:19:46 -04002034 auto framebufferIt = mFramebufferMap.find(0);
2035 if (framebufferIt != mFramebufferMap.end())
2036 {
2037 const Framebuffer *framebuffer = framebufferIt->second;
2038 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2039
2040 ASSERT(backAttachment != nullptr);
2041 return backAttachment->getSurface()->getRenderBuffer();
2042 }
2043 else
2044 {
2045 return EGL_NONE;
2046 }
Régis Fénéon83107972015-02-05 12:57:44 +01002047}
2048
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002049VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002050{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002051 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002052 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2053 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002054 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002055 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2056
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002057 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002058 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002059
2060 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002061}
2062
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002063TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002064{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002065 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002066 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2067 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002068 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002069 transformFeedback =
2070 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002071 transformFeedback->addRef();
2072 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002073 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002074
2075 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002076}
2077
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002078Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2079{
2080 // Can be called from Bind without a prior call to Gen.
2081 auto framebufferIt = mFramebufferMap.find(framebuffer);
2082 bool neverCreated = framebufferIt == mFramebufferMap.end();
2083 if (neverCreated || framebufferIt->second == nullptr)
2084 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002085 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002086 if (neverCreated)
2087 {
2088 mFramebufferHandleAllocator.reserve(framebuffer);
2089 mFramebufferMap[framebuffer] = newFBO;
2090 return newFBO;
2091 }
2092
2093 framebufferIt->second = newFBO;
2094 }
2095
2096 return framebufferIt->second;
2097}
2098
Geoff Lang36167ab2015-12-07 10:27:14 -05002099bool Context::isVertexArrayGenerated(GLuint vertexArray)
2100{
Geoff Langf41a7152016-09-19 15:11:17 -04002101 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002102 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2103}
2104
2105bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2106{
Geoff Langf41a7152016-09-19 15:11:17 -04002107 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002108 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2109}
2110
Shannon Woods53a94a82014-06-24 15:20:36 -04002111void Context::detachTexture(GLuint texture)
2112{
2113 // Simple pass-through to State's detachTexture method, as textures do not require
2114 // allocation map management either here or in the resource manager at detach time.
2115 // Zero textures are held by the Context, and we don't attempt to request them from
2116 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002117 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002118}
2119
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002120void Context::detachBuffer(GLuint buffer)
2121{
Yuly Novikov5807a532015-12-03 13:01:22 -05002122 // Simple pass-through to State's detachBuffer method, since
2123 // only buffer attachments to container objects that are bound to the current context
2124 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002125
Yuly Novikov5807a532015-12-03 13:01:22 -05002126 // [OpenGL ES 3.2] section 5.1.2 page 45:
2127 // Attachments to unbound container objects, such as
2128 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2129 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002130 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002131}
2132
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002133void Context::detachFramebuffer(GLuint framebuffer)
2134{
Shannon Woods53a94a82014-06-24 15:20:36 -04002135 // Framebuffer detachment is handled by Context, because 0 is a valid
2136 // Framebuffer object, and a pointer to it must be passed from Context
2137 // to State at binding time.
2138
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002139 // [OpenGL ES 2.0.24] section 4.4 page 107:
2140 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2141 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2142
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002143 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002144 {
2145 bindReadFramebuffer(0);
2146 }
2147
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002148 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002149 {
2150 bindDrawFramebuffer(0);
2151 }
2152}
2153
2154void Context::detachRenderbuffer(GLuint renderbuffer)
2155{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002156 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002157}
2158
Jamie Madill57a89722013-07-02 11:57:03 -04002159void Context::detachVertexArray(GLuint vertexArray)
2160{
Jamie Madill77a72f62015-04-14 11:18:32 -04002161 // Vertex array detachment is handled by Context, because 0 is a valid
2162 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002163 // binding time.
2164
Jamie Madill57a89722013-07-02 11:57:03 -04002165 // [OpenGL ES 3.0.2] section 2.10 page 43:
2166 // If a vertex array object that is currently bound is deleted, the binding
2167 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002168 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002169 {
2170 bindVertexArray(0);
2171 }
2172}
2173
Geoff Langc8058452014-02-03 12:04:11 -05002174void Context::detachTransformFeedback(GLuint transformFeedback)
2175{
Corentin Walleza2257da2016-04-19 16:43:12 -04002176 // Transform feedback detachment is handled by Context, because 0 is a valid
2177 // transform feedback, and a pointer to it must be passed from Context to State at
2178 // binding time.
2179
2180 // The OpenGL specification doesn't mention what should happen when the currently bound
2181 // transform feedback object is deleted. Since it is a container object, we treat it like
2182 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002183 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002184 {
2185 bindTransformFeedback(0);
2186 }
Geoff Langc8058452014-02-03 12:04:11 -05002187}
2188
Jamie Madilldc356042013-07-19 16:36:57 -04002189void Context::detachSampler(GLuint sampler)
2190{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002191 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002192}
2193
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002194void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2195{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002196 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002197}
2198
Jamie Madille29d1672013-07-19 16:36:57 -04002199void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2200{
Geoff Langc1984ed2016-10-07 12:41:00 -04002201 Sampler *samplerObject =
2202 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2203 SetSamplerParameteri(samplerObject, pname, param);
2204}
Jamie Madille29d1672013-07-19 16:36:57 -04002205
Geoff Langc1984ed2016-10-07 12:41:00 -04002206void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2207{
2208 Sampler *samplerObject =
2209 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2210 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002211}
2212
2213void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2214{
Geoff Langc1984ed2016-10-07 12:41:00 -04002215 Sampler *samplerObject =
2216 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2217 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002218}
2219
Geoff Langc1984ed2016-10-07 12:41:00 -04002220void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002221{
Geoff Langc1984ed2016-10-07 12:41:00 -04002222 Sampler *samplerObject =
2223 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2224 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002225}
2226
Geoff Langc1984ed2016-10-07 12:41:00 -04002227void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002228{
Geoff Langc1984ed2016-10-07 12:41:00 -04002229 const Sampler *samplerObject =
2230 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2231 QuerySamplerParameteriv(samplerObject, pname, params);
2232}
Jamie Madill9675b802013-07-19 16:36:59 -04002233
Geoff Langc1984ed2016-10-07 12:41:00 -04002234void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2235{
2236 const Sampler *samplerObject =
2237 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2238 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002239}
2240
Olli Etuahof0fee072016-03-30 15:11:58 +03002241void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2242{
2243 gl::Program *programObject = getProgram(program);
2244 ASSERT(programObject != nullptr);
2245
2246 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2247 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2248}
2249
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002250void Context::initRendererString()
2251{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002252 std::ostringstream rendererString;
2253 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002254 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002255 rendererString << ")";
2256
Geoff Langcec35902014-04-16 10:52:36 -04002257 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002258}
2259
Geoff Langc287ea62016-09-16 14:46:51 -04002260const char *Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002261{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002262 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002263}
2264
Geoff Langcec35902014-04-16 10:52:36 -04002265void Context::initExtensionStrings()
2266{
Geoff Langc287ea62016-09-16 14:46:51 -04002267 for (const auto &extensionString : mExtensions.getStrings())
2268 {
2269 mExtensionStrings.push_back(MakeStaticString(extensionString));
2270 }
Geoff Langcec35902014-04-16 10:52:36 -04002271
Geoff Langc0b9ef42014-07-02 10:02:37 -04002272 std::ostringstream combinedStringStream;
Geoff Langc287ea62016-09-16 14:46:51 -04002273 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(),
2274 std::ostream_iterator<const char *>(combinedStringStream, " "));
2275 mExtensionString = MakeStaticString(combinedStringStream.str());
Geoff Langcec35902014-04-16 10:52:36 -04002276}
2277
Geoff Langc287ea62016-09-16 14:46:51 -04002278const char *Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002279{
2280 return mExtensionString;
2281}
2282
Geoff Langc287ea62016-09-16 14:46:51 -04002283const char *Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002284{
2285 return mExtensionStrings[idx];
2286}
2287
2288size_t Context::getExtensionStringCount() const
2289{
2290 return mExtensionStrings.size();
2291}
2292
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002293void Context::beginTransformFeedback(GLenum primitiveMode)
2294{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002295 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002296 ASSERT(transformFeedback != nullptr);
2297 ASSERT(!transformFeedback->isPaused());
2298
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002299 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002300}
2301
2302bool Context::hasActiveTransformFeedback(GLuint program) const
2303{
2304 for (auto pair : mTransformFeedbackMap)
2305 {
2306 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2307 {
2308 return true;
2309 }
2310 }
2311 return false;
2312}
2313
Geoff Langc287ea62016-09-16 14:46:51 -04002314void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002315{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002316 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002317
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002318 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002319
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002320 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002321
Geoff Langeb66a6e2016-10-31 13:06:12 -04002322 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002323 {
2324 // Disable ES3+ extensions
2325 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002326 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002327 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002328 }
2329
Geoff Langeb66a6e2016-10-31 13:06:12 -04002330 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002331 {
2332 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2333 //mExtensions.sRGB = false;
2334 }
2335
Jamie Madill00ed7a12016-05-19 13:13:38 -04002336 // Some extensions are always available because they are implemented in the GL layer.
2337 mExtensions.bindUniformLocation = true;
2338 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002339 mExtensions.bindGeneratesResource = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002340
2341 // Enable the no error extension if the context was created with the flag.
2342 mExtensions.noError = mSkipValidation;
2343
Geoff Lang70d0f492015-12-10 17:45:46 -05002344 // Explicitly enable GL_KHR_debug
2345 mExtensions.debug = true;
2346 mExtensions.maxDebugMessageLength = 1024;
2347 mExtensions.maxDebugLoggedMessages = 1024;
2348 mExtensions.maxDebugGroupStackDepth = 1024;
2349 mExtensions.maxLabelLength = 1024;
2350
Geoff Langff5b2d52016-09-07 11:32:23 -04002351 // Explicitly enable GL_ANGLE_robust_client_memory
2352 mExtensions.robustClientMemory = true;
2353
Geoff Lang301d1612014-07-09 10:34:37 -04002354 // Apply implementation limits
2355 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002356 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2357 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2358
2359 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002360
Geoff Langc287ea62016-09-16 14:46:51 -04002361 // WebGL compatibility
2362 mExtensions.webglCompatibility = webGLContext;
2363 for (const auto &extensionInfo : GetExtensionInfoMap())
2364 {
2365 // If this context is for WebGL, disable all enableable extensions
2366 if (webGLContext && extensionInfo.second.Enableable)
2367 {
2368 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2369 }
2370 }
2371
2372 // Generate texture caps
2373 updateCaps();
2374}
2375
2376void Context::updateCaps()
2377{
Geoff Lang900013c2014-07-07 11:32:19 -04002378 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002379 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002380
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002381 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002382 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2383 {
2384 GLenum format = i->first;
2385 TextureCaps formatCaps = i->second;
2386
Geoff Lang5d601382014-07-22 15:14:06 -04002387 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002388
Geoff Lang0d8b7242015-09-09 14:56:53 -04002389 // Update the format caps based on the client version and extensions.
2390 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2391 // ES3.
2392 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002393 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002394 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002395 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002396 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002397 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002398
2399 // OpenGL ES does not support multisampling with integer formats
2400 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002401 {
Geoff Langd87878e2014-09-19 15:42:59 -04002402 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002403 }
Geoff Langd87878e2014-09-19 15:42:59 -04002404
2405 if (formatCaps.texturable && formatInfo.compressed)
2406 {
2407 mCaps.compressedTextureFormats.push_back(format);
2408 }
2409
2410 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002411 }
2412}
2413
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002414void Context::initWorkarounds()
2415{
2416 // Lose the context upon out of memory error if the application is
2417 // expecting to watch for those events.
2418 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2419}
2420
Jamie Madill1b94d432015-08-07 13:23:23 -04002421void Context::syncRendererState()
2422{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002423 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2424 mImplementation->syncState(mGLState, dirtyBits);
2425 mGLState.clearDirtyBits();
2426 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002427}
2428
Jamie Madillad9f24e2016-02-12 09:27:24 -05002429void Context::syncRendererState(const State::DirtyBits &bitMask,
2430 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002431{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002432 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2433 mImplementation->syncState(mGLState, dirtyBits);
2434 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002435
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002436 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002437}
Jamie Madillc29968b2016-01-20 11:17:23 -05002438
2439void Context::blitFramebuffer(GLint srcX0,
2440 GLint srcY0,
2441 GLint srcX1,
2442 GLint srcY1,
2443 GLint dstX0,
2444 GLint dstY0,
2445 GLint dstX1,
2446 GLint dstY1,
2447 GLbitfield mask,
2448 GLenum filter)
2449{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002450 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002451 ASSERT(drawFramebuffer);
2452
2453 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2454 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2455
Jamie Madillad9f24e2016-02-12 09:27:24 -05002456 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002457
Jamie Madill8415b5f2016-04-26 13:41:39 -04002458 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002459}
Jamie Madillc29968b2016-01-20 11:17:23 -05002460
2461void Context::clear(GLbitfield mask)
2462{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002463 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002464 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002465}
2466
2467void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2468{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002469 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002470 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2471 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002472}
2473
2474void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2475{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002476 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002477 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2478 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002479}
2480
2481void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2482{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002483 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002484 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2485 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002486}
2487
2488void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2489{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002490 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 ASSERT(framebufferObject);
2492
2493 // If a buffer is not present, the clear has no effect
2494 if (framebufferObject->getDepthbuffer() == nullptr &&
2495 framebufferObject->getStencilbuffer() == nullptr)
2496 {
2497 return;
2498 }
2499
Jamie Madillad9f24e2016-02-12 09:27:24 -05002500 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002501 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2502 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002503}
2504
2505void Context::readPixels(GLint x,
2506 GLint y,
2507 GLsizei width,
2508 GLsizei height,
2509 GLenum format,
2510 GLenum type,
2511 GLvoid *pixels)
2512{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002513 if (width == 0 || height == 0)
2514 {
2515 return;
2516 }
2517
Jamie Madillad9f24e2016-02-12 09:27:24 -05002518 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002519
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002520 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002521 ASSERT(framebufferObject);
2522
2523 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002524 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002525}
2526
2527void Context::copyTexImage2D(GLenum target,
2528 GLint level,
2529 GLenum internalformat,
2530 GLint x,
2531 GLint y,
2532 GLsizei width,
2533 GLsizei height,
2534 GLint border)
2535{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002536 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002537 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002538
Jamie Madillc29968b2016-01-20 11:17:23 -05002539 Rectangle sourceArea(x, y, width, height);
2540
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002541 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002542 Texture *texture =
2543 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002544 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002545}
2546
2547void Context::copyTexSubImage2D(GLenum target,
2548 GLint level,
2549 GLint xoffset,
2550 GLint yoffset,
2551 GLint x,
2552 GLint y,
2553 GLsizei width,
2554 GLsizei height)
2555{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002556 if (width == 0 || height == 0)
2557 {
2558 return;
2559 }
2560
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002561 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002562 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002563
Jamie Madillc29968b2016-01-20 11:17:23 -05002564 Offset destOffset(xoffset, yoffset, 0);
2565 Rectangle sourceArea(x, y, width, height);
2566
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002567 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002568 Texture *texture =
2569 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002570 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002571}
2572
2573void Context::copyTexSubImage3D(GLenum target,
2574 GLint level,
2575 GLint xoffset,
2576 GLint yoffset,
2577 GLint zoffset,
2578 GLint x,
2579 GLint y,
2580 GLsizei width,
2581 GLsizei height)
2582{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002583 if (width == 0 || height == 0)
2584 {
2585 return;
2586 }
2587
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002588 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002589 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002590
Jamie Madillc29968b2016-01-20 11:17:23 -05002591 Offset destOffset(xoffset, yoffset, zoffset);
2592 Rectangle sourceArea(x, y, width, height);
2593
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002594 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002595 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002596 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002597}
2598
2599void Context::framebufferTexture2D(GLenum target,
2600 GLenum attachment,
2601 GLenum textarget,
2602 GLuint texture,
2603 GLint level)
2604{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002605 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002606 ASSERT(framebuffer);
2607
2608 if (texture != 0)
2609 {
2610 Texture *textureObj = getTexture(texture);
2611
2612 ImageIndex index = ImageIndex::MakeInvalid();
2613
2614 if (textarget == GL_TEXTURE_2D)
2615 {
2616 index = ImageIndex::Make2D(level);
2617 }
2618 else
2619 {
2620 ASSERT(IsCubeMapTextureTarget(textarget));
2621 index = ImageIndex::MakeCube(textarget, level);
2622 }
2623
2624 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2625 }
2626 else
2627 {
2628 framebuffer->resetAttachment(attachment);
2629 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002630
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002631 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002632}
2633
2634void Context::framebufferRenderbuffer(GLenum target,
2635 GLenum attachment,
2636 GLenum renderbuffertarget,
2637 GLuint renderbuffer)
2638{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002639 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002640 ASSERT(framebuffer);
2641
2642 if (renderbuffer != 0)
2643 {
2644 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2645 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2646 renderbufferObject);
2647 }
2648 else
2649 {
2650 framebuffer->resetAttachment(attachment);
2651 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002652
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002653 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002654}
2655
2656void Context::framebufferTextureLayer(GLenum target,
2657 GLenum attachment,
2658 GLuint texture,
2659 GLint level,
2660 GLint layer)
2661{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002662 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002663 ASSERT(framebuffer);
2664
2665 if (texture != 0)
2666 {
2667 Texture *textureObject = getTexture(texture);
2668
2669 ImageIndex index = ImageIndex::MakeInvalid();
2670
2671 if (textureObject->getTarget() == GL_TEXTURE_3D)
2672 {
2673 index = ImageIndex::Make3D(level, layer);
2674 }
2675 else
2676 {
2677 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2678 index = ImageIndex::Make2DArray(level, layer);
2679 }
2680
2681 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2682 }
2683 else
2684 {
2685 framebuffer->resetAttachment(attachment);
2686 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002687
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002688 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002689}
2690
2691void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2692{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002693 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002694 ASSERT(framebuffer);
2695 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002696 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002697}
2698
2699void Context::readBuffer(GLenum mode)
2700{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002701 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002702 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002703 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002704}
2705
2706void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2707{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002708 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002709 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002710
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002711 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002712 ASSERT(framebuffer);
2713
2714 // The specification isn't clear what should be done when the framebuffer isn't complete.
2715 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002716 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002717}
2718
2719void Context::invalidateFramebuffer(GLenum target,
2720 GLsizei numAttachments,
2721 const GLenum *attachments)
2722{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002723 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002724 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002725
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002726 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002727 ASSERT(framebuffer);
2728
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002729 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002730 {
Jamie Madill437fa652016-05-03 15:13:24 -04002731 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002732 }
Jamie Madill437fa652016-05-03 15:13:24 -04002733
2734 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002735}
2736
2737void Context::invalidateSubFramebuffer(GLenum target,
2738 GLsizei numAttachments,
2739 const GLenum *attachments,
2740 GLint x,
2741 GLint y,
2742 GLsizei width,
2743 GLsizei height)
2744{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002745 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002746 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002747
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002748 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002749 ASSERT(framebuffer);
2750
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002751 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002752 {
Jamie Madill437fa652016-05-03 15:13:24 -04002753 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002754 }
Jamie Madill437fa652016-05-03 15:13:24 -04002755
2756 Rectangle area(x, y, width, height);
2757 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002758}
2759
Jamie Madill73a84962016-02-12 09:27:23 -05002760void Context::texImage2D(GLenum target,
2761 GLint level,
2762 GLint internalformat,
2763 GLsizei width,
2764 GLsizei height,
2765 GLint border,
2766 GLenum format,
2767 GLenum type,
2768 const GLvoid *pixels)
2769{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002770 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002771
2772 Extents size(width, height, 1);
2773 Texture *texture =
2774 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002775 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002776 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002777}
2778
2779void Context::texImage3D(GLenum target,
2780 GLint level,
2781 GLint internalformat,
2782 GLsizei width,
2783 GLsizei height,
2784 GLsizei depth,
2785 GLint border,
2786 GLenum format,
2787 GLenum type,
2788 const GLvoid *pixels)
2789{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002790 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002791
2792 Extents size(width, height, depth);
2793 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002794 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002795 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002796}
2797
2798void Context::texSubImage2D(GLenum target,
2799 GLint level,
2800 GLint xoffset,
2801 GLint yoffset,
2802 GLsizei width,
2803 GLsizei height,
2804 GLenum format,
2805 GLenum type,
2806 const GLvoid *pixels)
2807{
2808 // Zero sized uploads are valid but no-ops
2809 if (width == 0 || height == 0)
2810 {
2811 return;
2812 }
2813
Jamie Madillad9f24e2016-02-12 09:27:24 -05002814 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002815
2816 Box area(xoffset, yoffset, 0, width, height, 1);
2817 Texture *texture =
2818 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002820 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002821}
2822
2823void Context::texSubImage3D(GLenum target,
2824 GLint level,
2825 GLint xoffset,
2826 GLint yoffset,
2827 GLint zoffset,
2828 GLsizei width,
2829 GLsizei height,
2830 GLsizei depth,
2831 GLenum format,
2832 GLenum type,
2833 const GLvoid *pixels)
2834{
2835 // Zero sized uploads are valid but no-ops
2836 if (width == 0 || height == 0 || depth == 0)
2837 {
2838 return;
2839 }
2840
Jamie Madillad9f24e2016-02-12 09:27:24 -05002841 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002842
2843 Box area(xoffset, yoffset, zoffset, width, height, depth);
2844 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002845 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002846 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002847}
2848
2849void Context::compressedTexImage2D(GLenum target,
2850 GLint level,
2851 GLenum internalformat,
2852 GLsizei width,
2853 GLsizei height,
2854 GLint border,
2855 GLsizei imageSize,
2856 const GLvoid *data)
2857{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002858 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002859
2860 Extents size(width, height, 1);
2861 Texture *texture =
2862 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002863 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2864 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002865 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002866}
2867
2868void Context::compressedTexImage3D(GLenum target,
2869 GLint level,
2870 GLenum internalformat,
2871 GLsizei width,
2872 GLsizei height,
2873 GLsizei depth,
2874 GLint border,
2875 GLsizei imageSize,
2876 const GLvoid *data)
2877{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002878 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002879
2880 Extents size(width, height, depth);
2881 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002882 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2883 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002884 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002885}
2886
2887void Context::compressedTexSubImage2D(GLenum target,
2888 GLint level,
2889 GLint xoffset,
2890 GLint yoffset,
2891 GLsizei width,
2892 GLsizei height,
2893 GLenum format,
2894 GLsizei imageSize,
2895 const GLvoid *data)
2896{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002897 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002898
2899 Box area(xoffset, yoffset, 0, width, height, 1);
2900 Texture *texture =
2901 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002902 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2903 format, imageSize,
2904 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002905}
2906
2907void Context::compressedTexSubImage3D(GLenum target,
2908 GLint level,
2909 GLint xoffset,
2910 GLint yoffset,
2911 GLint zoffset,
2912 GLsizei width,
2913 GLsizei height,
2914 GLsizei depth,
2915 GLenum format,
2916 GLsizei imageSize,
2917 const GLvoid *data)
2918{
2919 // Zero sized uploads are valid but no-ops
2920 if (width == 0 || height == 0)
2921 {
2922 return;
2923 }
2924
Jamie Madillad9f24e2016-02-12 09:27:24 -05002925 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002926
2927 Box area(xoffset, yoffset, zoffset, width, height, depth);
2928 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002929 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2930 format, imageSize,
2931 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002932}
2933
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002934void Context::generateMipmap(GLenum target)
2935{
2936 Texture *texture = getTargetTexture(target);
2937 handleError(texture->generateMipmap());
2938}
2939
Geoff Langc287ea62016-09-16 14:46:51 -04002940GLboolean Context::enableExtension(const char *name)
2941{
2942 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2943 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2944 const auto &extension = extensionInfos.at(name);
2945 ASSERT(extension.Enableable);
2946
2947 if (mExtensions.*(extension.ExtensionsMember))
2948 {
2949 // Extension already enabled
2950 return GL_TRUE;
2951 }
2952
2953 const auto &nativeExtensions = mImplementation->getNativeExtensions();
2954 if (!(nativeExtensions.*(extension.ExtensionsMember)))
2955 {
2956 // Underlying implementation does not support this valid extension
2957 return GL_FALSE;
2958 }
2959
2960 mExtensions.*(extension.ExtensionsMember) = true;
2961 updateCaps();
2962 initExtensionStrings();
2963 return GL_TRUE;
2964}
2965
Geoff Lang97073d12016-04-20 10:42:34 -07002966void Context::copyTextureCHROMIUM(GLuint sourceId,
2967 GLuint destId,
2968 GLint internalFormat,
2969 GLenum destType,
2970 GLboolean unpackFlipY,
2971 GLboolean unpackPremultiplyAlpha,
2972 GLboolean unpackUnmultiplyAlpha)
2973{
2974 syncStateForTexImage();
2975
2976 gl::Texture *sourceTexture = getTexture(sourceId);
2977 gl::Texture *destTexture = getTexture(destId);
2978 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
2979 unpackPremultiplyAlpha == GL_TRUE,
2980 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
2981}
2982
2983void Context::copySubTextureCHROMIUM(GLuint sourceId,
2984 GLuint destId,
2985 GLint xoffset,
2986 GLint yoffset,
2987 GLint x,
2988 GLint y,
2989 GLsizei width,
2990 GLsizei height,
2991 GLboolean unpackFlipY,
2992 GLboolean unpackPremultiplyAlpha,
2993 GLboolean unpackUnmultiplyAlpha)
2994{
2995 // Zero sized copies are valid but no-ops
2996 if (width == 0 || height == 0)
2997 {
2998 return;
2999 }
3000
3001 syncStateForTexImage();
3002
3003 gl::Texture *sourceTexture = getTexture(sourceId);
3004 gl::Texture *destTexture = getTexture(destId);
3005 Offset offset(xoffset, yoffset, 0);
3006 Rectangle area(x, y, width, height);
3007 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3008 unpackPremultiplyAlpha == GL_TRUE,
3009 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3010}
3011
Geoff Lang47110bf2016-04-20 11:13:22 -07003012void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3013{
3014 syncStateForTexImage();
3015
3016 gl::Texture *sourceTexture = getTexture(sourceId);
3017 gl::Texture *destTexture = getTexture(destId);
3018 handleError(destTexture->copyCompressedTexture(sourceTexture));
3019}
3020
Geoff Lang496c02d2016-10-20 11:38:11 -07003021void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003022{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003023 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003024 ASSERT(buffer);
3025
Geoff Lang496c02d2016-10-20 11:38:11 -07003026 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003027}
3028
3029GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3030{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003031 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003032 ASSERT(buffer);
3033
3034 Error error = buffer->map(access);
3035 if (error.isError())
3036 {
Jamie Madill437fa652016-05-03 15:13:24 -04003037 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003038 return nullptr;
3039 }
3040
3041 return buffer->getMapPointer();
3042}
3043
3044GLboolean Context::unmapBuffer(GLenum target)
3045{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003046 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003047 ASSERT(buffer);
3048
3049 GLboolean result;
3050 Error error = buffer->unmap(&result);
3051 if (error.isError())
3052 {
Jamie Madill437fa652016-05-03 15:13:24 -04003053 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003054 return GL_FALSE;
3055 }
3056
3057 return result;
3058}
3059
3060GLvoid *Context::mapBufferRange(GLenum target,
3061 GLintptr offset,
3062 GLsizeiptr length,
3063 GLbitfield access)
3064{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003065 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003066 ASSERT(buffer);
3067
3068 Error error = buffer->mapRange(offset, length, access);
3069 if (error.isError())
3070 {
Jamie Madill437fa652016-05-03 15:13:24 -04003071 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003072 return nullptr;
3073 }
3074
3075 return buffer->getMapPointer();
3076}
3077
3078void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3079{
3080 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3081}
3082
Jamie Madillad9f24e2016-02-12 09:27:24 -05003083void Context::syncStateForReadPixels()
3084{
3085 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3086}
3087
3088void Context::syncStateForTexImage()
3089{
3090 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3091}
3092
3093void Context::syncStateForClear()
3094{
3095 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3096}
3097
3098void Context::syncStateForBlit()
3099{
3100 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3101}
3102
Jamie Madillc20ab272016-06-09 07:20:46 -07003103void Context::activeTexture(GLenum texture)
3104{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003105 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003106}
3107
3108void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3109{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003110 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003111}
3112
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003113void Context::blendEquation(GLenum mode)
3114{
3115 mGLState.setBlendEquation(mode, mode);
3116}
3117
Jamie Madillc20ab272016-06-09 07:20:46 -07003118void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3119{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003120 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003121}
3122
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003123void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3124{
3125 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3126}
3127
Jamie Madillc20ab272016-06-09 07:20:46 -07003128void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3129{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003130 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003131}
3132
3133void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3134{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003135 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003136}
3137
3138void Context::clearDepthf(GLclampf depth)
3139{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003140 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003141}
3142
3143void Context::clearStencil(GLint s)
3144{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003145 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003146}
3147
3148void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3149{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003150 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003151}
3152
3153void Context::cullFace(GLenum mode)
3154{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003155 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003156}
3157
3158void Context::depthFunc(GLenum func)
3159{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003160 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003161}
3162
3163void Context::depthMask(GLboolean flag)
3164{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003165 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003166}
3167
3168void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3169{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003170 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003171}
3172
3173void Context::disable(GLenum cap)
3174{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003175 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003176}
3177
3178void Context::disableVertexAttribArray(GLuint index)
3179{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003180 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003181}
3182
3183void Context::enable(GLenum cap)
3184{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003185 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003186}
3187
3188void Context::enableVertexAttribArray(GLuint index)
3189{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003190 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003191}
3192
3193void Context::frontFace(GLenum mode)
3194{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003195 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003196}
3197
3198void Context::hint(GLenum target, GLenum mode)
3199{
3200 switch (target)
3201 {
3202 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003203 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003204 break;
3205
3206 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003207 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003208 break;
3209
3210 default:
3211 UNREACHABLE();
3212 return;
3213 }
3214}
3215
3216void Context::lineWidth(GLfloat width)
3217{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003218 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003219}
3220
3221void Context::pixelStorei(GLenum pname, GLint param)
3222{
3223 switch (pname)
3224 {
3225 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003226 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003227 break;
3228
3229 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003230 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003231 break;
3232
3233 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003234 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003235 break;
3236
3237 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003238 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003239 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003240 break;
3241
3242 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003243 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003244 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003245 break;
3246
3247 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003248 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003249 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003250 break;
3251
3252 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003253 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003254 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003255 break;
3256
3257 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003258 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003259 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003260 break;
3261
3262 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003263 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003264 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003265 break;
3266
3267 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003268 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003269 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003270 break;
3271
3272 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003273 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003274 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003275 break;
3276
3277 default:
3278 UNREACHABLE();
3279 return;
3280 }
3281}
3282
3283void Context::polygonOffset(GLfloat factor, GLfloat units)
3284{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003285 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003286}
3287
3288void Context::sampleCoverage(GLclampf value, GLboolean invert)
3289{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003290 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003291}
3292
3293void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3294{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003295 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003296}
3297
3298void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3299{
3300 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3301 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003302 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003303 }
3304
3305 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3306 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003307 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003308 }
3309}
3310
3311void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3312{
3313 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3314 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003315 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003316 }
3317
3318 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3319 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003320 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003321 }
3322}
3323
3324void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3325{
3326 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3327 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003328 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003329 }
3330
3331 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3332 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003333 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003334 }
3335}
3336
3337void Context::vertexAttrib1f(GLuint index, GLfloat x)
3338{
3339 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003340 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003341}
3342
3343void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3344{
3345 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003346 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003347}
3348
3349void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3350{
3351 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003352 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003353}
3354
3355void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3356{
3357 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003358 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003359}
3360
3361void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3362{
3363 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365}
3366
3367void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3368{
3369 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003370 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003371}
3372
3373void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3374{
3375 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003376 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003377}
3378
3379void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3380{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003381 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003382}
3383
3384void Context::vertexAttribPointer(GLuint index,
3385 GLint size,
3386 GLenum type,
3387 GLboolean normalized,
3388 GLsizei stride,
3389 const GLvoid *ptr)
3390{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003391 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3392 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003393}
3394
3395void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3396{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003397 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003398}
3399
3400void Context::vertexAttribIPointer(GLuint index,
3401 GLint size,
3402 GLenum type,
3403 GLsizei stride,
3404 const GLvoid *pointer)
3405{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003406 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3407 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003408}
3409
3410void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3411{
3412 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003414}
3415
3416void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3417{
3418 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420}
3421
3422void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3423{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425}
3426
3427void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3428{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003429 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003430}
3431
3432void Context::debugMessageControl(GLenum source,
3433 GLenum type,
3434 GLenum severity,
3435 GLsizei count,
3436 const GLuint *ids,
3437 GLboolean enabled)
3438{
3439 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003440 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3441 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003442}
3443
3444void Context::debugMessageInsert(GLenum source,
3445 GLenum type,
3446 GLuint id,
3447 GLenum severity,
3448 GLsizei length,
3449 const GLchar *buf)
3450{
3451 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003452 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003453}
3454
3455void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3456{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003457 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003458}
3459
3460GLuint Context::getDebugMessageLog(GLuint count,
3461 GLsizei bufSize,
3462 GLenum *sources,
3463 GLenum *types,
3464 GLuint *ids,
3465 GLenum *severities,
3466 GLsizei *lengths,
3467 GLchar *messageLog)
3468{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003469 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3470 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003471}
3472
3473void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3474{
3475 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003476 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003477}
3478
3479void Context::popDebugGroup()
3480{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003481 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003482}
3483
Jamie Madill29639852016-09-02 15:00:09 -04003484void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3485{
3486 Buffer *buffer = mGLState.getTargetBuffer(target);
3487 ASSERT(buffer);
3488 handleError(buffer->bufferData(target, data, size, usage));
3489}
3490
3491void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3492{
3493 if (data == nullptr)
3494 {
3495 return;
3496 }
3497
3498 Buffer *buffer = mGLState.getTargetBuffer(target);
3499 ASSERT(buffer);
3500 handleError(buffer->bufferSubData(target, data, size, offset));
3501}
3502
Jamie Madillef300b12016-10-07 15:12:09 -04003503void Context::attachShader(GLuint program, GLuint shader)
3504{
3505 auto programObject = mResourceManager->getProgram(program);
3506 auto shaderObject = mResourceManager->getShader(shader);
3507 ASSERT(programObject && shaderObject);
3508 programObject->attachShader(shaderObject);
3509}
3510
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003511const Workarounds &Context::getWorkarounds() const
3512{
3513 return mWorkarounds;
3514}
3515
Jamie Madillb0817d12016-11-01 15:48:31 -04003516void Context::copyBufferSubData(GLenum readTarget,
3517 GLenum writeTarget,
3518 GLintptr readOffset,
3519 GLintptr writeOffset,
3520 GLsizeiptr size)
3521{
3522 // if size is zero, the copy is a successful no-op
3523 if (size == 0)
3524 {
3525 return;
3526 }
3527
3528 // TODO(jmadill): cache these.
3529 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3530 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3531
3532 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3533}
3534
Jamie Madill01a80ee2016-11-07 12:06:18 -05003535void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3536{
3537 Program *programObject = getProgram(program);
3538 // TODO(jmadill): Re-use this from the validation if possible.
3539 ASSERT(programObject);
3540 programObject->bindAttributeLocation(index, name);
3541}
3542
3543void Context::bindBuffer(GLenum target, GLuint buffer)
3544{
3545 switch (target)
3546 {
3547 case GL_ARRAY_BUFFER:
3548 bindArrayBuffer(buffer);
3549 break;
3550 case GL_ELEMENT_ARRAY_BUFFER:
3551 bindElementArrayBuffer(buffer);
3552 break;
3553 case GL_COPY_READ_BUFFER:
3554 bindCopyReadBuffer(buffer);
3555 break;
3556 case GL_COPY_WRITE_BUFFER:
3557 bindCopyWriteBuffer(buffer);
3558 break;
3559 case GL_PIXEL_PACK_BUFFER:
3560 bindPixelPackBuffer(buffer);
3561 break;
3562 case GL_PIXEL_UNPACK_BUFFER:
3563 bindPixelUnpackBuffer(buffer);
3564 break;
3565 case GL_UNIFORM_BUFFER:
3566 bindGenericUniformBuffer(buffer);
3567 break;
3568 case GL_TRANSFORM_FEEDBACK_BUFFER:
3569 bindGenericTransformFeedbackBuffer(buffer);
3570 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003571 case GL_ATOMIC_COUNTER_BUFFER:
3572 UNIMPLEMENTED();
3573 break;
3574 case GL_SHADER_STORAGE_BUFFER:
3575 UNIMPLEMENTED();
3576 break;
3577 case GL_DRAW_INDIRECT_BUFFER:
3578 UNIMPLEMENTED();
3579 break;
3580 case GL_DISPATCH_INDIRECT_BUFFER:
3581 UNIMPLEMENTED();
3582 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003583
3584 default:
3585 UNREACHABLE();
3586 break;
3587 }
3588}
3589
3590void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3591{
3592 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3593 {
3594 bindReadFramebuffer(framebuffer);
3595 }
3596
3597 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3598 {
3599 bindDrawFramebuffer(framebuffer);
3600 }
3601}
3602
3603void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3604{
3605 ASSERT(target == GL_RENDERBUFFER);
3606 Renderbuffer *object =
3607 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
3608 mGLState.setRenderbufferBinding(object);
3609}
3610
Jamie Madillc29968b2016-01-20 11:17:23 -05003611} // namespace gl