blob: 8b31eb4ee673ae847433b3d2d8935640a1f96308 [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
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500152GLenum GetResetStrategy(const egl::AttributeMap &attribs)
153{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400154 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
155 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500156 switch (attrib)
157 {
158 case EGL_NO_RESET_NOTIFICATION:
159 return GL_NO_RESET_NOTIFICATION_EXT;
160 case EGL_LOSE_CONTEXT_ON_RESET:
161 return GL_LOSE_CONTEXT_ON_RESET_EXT;
162 default:
163 UNREACHABLE();
164 return GL_NONE;
165 }
166}
167
168bool GetRobustAccess(const egl::AttributeMap &attribs)
169{
170 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
171}
172
173bool GetDebug(const egl::AttributeMap &attribs)
174{
175 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
176}
177
178bool GetNoError(const egl::AttributeMap &attribs)
179{
180 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
181}
182
Geoff Langc287ea62016-09-16 14:46:51 -0400183bool GetWebGLContext(const egl::AttributeMap &attribs)
184{
185 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
186}
187
Geoff Langf41a7152016-09-19 15:11:17 -0400188bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
189{
190 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
191}
192
Martin Radev9d901792016-07-15 15:58:58 +0300193std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
194{
195 std::string labelName;
196 if (label != nullptr)
197 {
198 size_t labelLength = length < 0 ? strlen(label) : length;
199 labelName = std::string(label, labelLength);
200 }
201 return labelName;
202}
203
204void GetObjectLabelBase(const std::string &objectLabel,
205 GLsizei bufSize,
206 GLsizei *length,
207 GLchar *label)
208{
209 size_t writeLength = objectLabel.length();
210 if (label != nullptr && bufSize > 0)
211 {
212 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
213 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
214 label[writeLength] = '\0';
215 }
216
217 if (length != nullptr)
218 {
219 *length = static_cast<GLsizei>(writeLength);
220 }
221}
222
Geoff Langf6db0982015-08-25 13:04:00 -0400223} // anonymous namespace
224
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000225namespace gl
226{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000227
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400228Context::Context(rx::EGLImplFactory *implFactory,
229 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400230 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500231 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300232
233 : ValidationContext(GetClientMajorVersion(attribs),
234 GetClientMinorVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700235 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500236 mCaps,
237 mTextureCaps,
238 mExtensions,
239 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500240 mLimitations,
241 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700242 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500243 mCompiler(nullptr),
Martin Radev1be913c2016-07-11 17:59:16 +0300244 mClientMajorVersion(GetClientMajorVersion(attribs)),
245 mClientMinorVersion(GetClientMinorVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400246 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500247 mClientType(EGL_OPENGL_ES_API),
248 mHasBeenCurrent(false),
249 mContextLost(false),
250 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700251 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500252 mResetStrategy(GetResetStrategy(attribs)),
253 mRobustAccess(GetRobustAccess(attribs)),
254 mCurrentSurface(nullptr),
255 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000256{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500257 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000258
Geoff Langc287ea62016-09-16 14:46:51 -0400259 initCaps(GetWebGLContext(attribs));
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700260 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400261
Geoff Langf41a7152016-09-19 15:11:17 -0400262 mGLState.initialize(mCaps, mExtensions, mClientMajorVersion, GetDebug(attribs),
263 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100264
Shannon Woods53a94a82014-06-24 15:20:36 -0400265 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400266
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400267 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000268 {
269 mResourceManager = shareContext->mResourceManager;
270 mResourceManager->addRef();
271 }
272 else
273 {
Jamie Madill901b3792016-05-26 09:20:40 -0400274 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000275 }
276
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700277 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400278
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000279 // [OpenGL ES 2.0.24] section 3.7 page 83:
280 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
281 // and cube map texture state vectors respectively associated with them.
282 // In order that access to these initial textures not be lost, they are treated as texture
283 // objects all of whose names are 0.
284
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400285 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500286 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500287
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400288 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500289 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400290
Martin Radev1be913c2016-07-11 17:59:16 +0300291 if (mClientMajorVersion >= 3)
Geoff Lang76b10c92014-09-05 16:28:14 -0400292 {
293 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500298 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400299 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000300
Ian Ewellbda75592016-04-18 17:25:54 -0400301 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
302 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTextureExternal =
304 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400305 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
306 }
307
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700308 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500309
Jamie Madill57a89722013-07-02 11:57:03 -0400310 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000311 bindArrayBuffer(0);
312 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400313
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000314 bindRenderbuffer(0);
315
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000316 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400317 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000318 {
319 bindIndexedUniformBuffer(0, i, 0, -1);
320 }
321
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000322 bindCopyReadBuffer(0);
323 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000324 bindPixelPackBuffer(0);
325 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000326
Martin Radev1be913c2016-07-11 17:59:16 +0300327 if (mClientMajorVersion >= 3)
Geoff Lang1a683462015-09-29 15:09:59 -0400328 {
329 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
330 // In the initial state, a default transform feedback object is bound and treated as
331 // a transform feedback object with a name of zero. That object is bound any time
332 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400333 bindTransformFeedback(0);
334 }
Geoff Langc8058452014-02-03 12:04:11 -0500335
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700336 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500337
338 // Initialize dirty bit masks
339 // TODO(jmadill): additional ES3 state
340 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
341 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
342 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
343 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
344 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
345 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400346 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500347 // No dirty objects.
348
349 // Readpixels uses the pack state and read FBO
350 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
351 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
352 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
353 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
354 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400355 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500356 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
357
358 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
359 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
360 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
361 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
362 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
363 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
364 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
365 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
366 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
367 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
368 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
369 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
370
371 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
372 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700373 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500374 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
375 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400376
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400377 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000378}
379
380Context::~Context()
381{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700382 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000383
Corentin Wallez37c39792015-08-20 14:19:46 -0400384 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000385 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400386 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400387 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400388 {
389 SafeDelete(framebuffer.second);
390 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000391 }
392
Corentin Wallez80b24112015-08-25 16:41:57 -0400393 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000394 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400395 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000396 }
397
Corentin Wallez80b24112015-08-25 16:41:57 -0400398 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000399 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400400 if (query.second != nullptr)
401 {
402 query.second->release();
403 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000404 }
405
Corentin Wallez80b24112015-08-25 16:41:57 -0400406 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400407 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400408 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400409 }
410
Corentin Wallez80b24112015-08-25 16:41:57 -0400411 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500412 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500413 if (transformFeedback.second != nullptr)
414 {
415 transformFeedback.second->release();
416 }
Geoff Langc8058452014-02-03 12:04:11 -0500417 }
418
Jamie Madilldedd7b92014-11-05 16:30:36 -0500419 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400420 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500421 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400422 }
423 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000424
Corentin Wallez51706ea2015-08-07 14:39:22 -0400425 if (mCurrentSurface != nullptr)
426 {
427 releaseSurface();
428 }
429
Jamie Madill1e9ae072014-11-06 15:27:21 -0500430 if (mResourceManager)
431 {
432 mResourceManager->release();
433 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500434
435 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000436}
437
daniel@transgaming.comad629872012-11-28 19:32:06 +0000438void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000439{
Jamie Madill77a72f62015-04-14 11:18:32 -0400440 ASSERT(surface != nullptr);
441
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000442 if (!mHasBeenCurrent)
443 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000444 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400445 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000446
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700447 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
448 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000449
450 mHasBeenCurrent = true;
451 }
452
Jamie Madill1b94d432015-08-07 13:23:23 -0400453 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700454 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400455
Corentin Wallez51706ea2015-08-07 14:39:22 -0400456 if (mCurrentSurface)
457 {
458 releaseSurface();
459 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000460 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400461 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000462
Corentin Wallez37c39792015-08-20 14:19:46 -0400463 // Update default framebuffer, the binding of the previous default
464 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400465 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400466 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700467 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400468 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700469 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400470 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700471 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400472 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700473 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400474 }
475 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400476 }
Ian Ewell292f0052016-02-04 10:37:32 -0500477
478 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700479 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000480}
481
Jamie Madill77a72f62015-04-14 11:18:32 -0400482void Context::releaseSurface()
483{
Corentin Wallez37c39792015-08-20 14:19:46 -0400484 ASSERT(mCurrentSurface != nullptr);
485
486 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400487 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400488 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700489 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400490 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700491 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400492 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700493 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400494 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700495 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400496 }
497 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400498 }
499
Corentin Wallez51706ea2015-08-07 14:39:22 -0400500 mCurrentSurface->setIsCurrent(false);
501 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400502}
503
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000504GLuint Context::createBuffer()
505{
506 return mResourceManager->createBuffer();
507}
508
509GLuint Context::createProgram()
510{
Jamie Madill901b3792016-05-26 09:20:40 -0400511 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000512}
513
514GLuint Context::createShader(GLenum type)
515{
Jamie Madill901b3792016-05-26 09:20:40 -0400516 return mResourceManager->createShader(mImplementation.get(),
517 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000518}
519
520GLuint Context::createTexture()
521{
522 return mResourceManager->createTexture();
523}
524
525GLuint Context::createRenderbuffer()
526{
527 return mResourceManager->createRenderbuffer();
528}
529
Geoff Lang882033e2014-09-30 11:26:07 -0400530GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400531{
Jamie Madill901b3792016-05-26 09:20:40 -0400532 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400533
Cooper Partind8e62a32015-01-29 15:21:25 -0800534 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400535}
536
Sami Väisänene45e53b2016-05-25 10:36:04 +0300537GLuint Context::createPaths(GLsizei range)
538{
539 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
540 if (resultOrError.isError())
541 {
542 handleError(resultOrError.getError());
543 return 0;
544 }
545 return resultOrError.getResult();
546}
547
Jamie Madill57a89722013-07-02 11:57:03 -0400548GLuint Context::createVertexArray()
549{
Geoff Lang36167ab2015-12-07 10:27:14 -0500550 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
551 mVertexArrayMap[vertexArray] = nullptr;
552 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400553}
554
Jamie Madilldc356042013-07-19 16:36:57 -0400555GLuint Context::createSampler()
556{
557 return mResourceManager->createSampler();
558}
559
Geoff Langc8058452014-02-03 12:04:11 -0500560GLuint Context::createTransformFeedback()
561{
Geoff Lang36167ab2015-12-07 10:27:14 -0500562 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
563 mTransformFeedbackMap[transformFeedback] = nullptr;
564 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500565}
566
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000567// Returns an unused framebuffer name
568GLuint Context::createFramebuffer()
569{
570 GLuint handle = mFramebufferHandleAllocator.allocate();
571
572 mFramebufferMap[handle] = NULL;
573
574 return handle;
575}
576
Jamie Madill33dc8432013-07-26 11:55:05 -0400577GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000578{
Jamie Madill33dc8432013-07-26 11:55:05 -0400579 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400581 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000582
583 return handle;
584}
585
586// Returns an unused query name
587GLuint Context::createQuery()
588{
589 GLuint handle = mQueryHandleAllocator.allocate();
590
591 mQueryMap[handle] = NULL;
592
593 return handle;
594}
595
596void Context::deleteBuffer(GLuint buffer)
597{
598 if (mResourceManager->getBuffer(buffer))
599 {
600 detachBuffer(buffer);
601 }
Jamie Madill893ab082014-05-16 16:56:10 -0400602
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603 mResourceManager->deleteBuffer(buffer);
604}
605
606void Context::deleteShader(GLuint shader)
607{
608 mResourceManager->deleteShader(shader);
609}
610
611void Context::deleteProgram(GLuint program)
612{
613 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000614}
615
616void Context::deleteTexture(GLuint texture)
617{
618 if (mResourceManager->getTexture(texture))
619 {
620 detachTexture(texture);
621 }
622
623 mResourceManager->deleteTexture(texture);
624}
625
626void Context::deleteRenderbuffer(GLuint renderbuffer)
627{
628 if (mResourceManager->getRenderbuffer(renderbuffer))
629 {
630 detachRenderbuffer(renderbuffer);
631 }
Jamie Madill893ab082014-05-16 16:56:10 -0400632
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633 mResourceManager->deleteRenderbuffer(renderbuffer);
634}
635
Jamie Madillcd055f82013-07-26 11:55:15 -0400636void Context::deleteFenceSync(GLsync fenceSync)
637{
638 // The spec specifies the underlying Fence object is not deleted until all current
639 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
640 // and since our API is currently designed for being called from a single thread, we can delete
641 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700642 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400643}
644
Sami Väisänene45e53b2016-05-25 10:36:04 +0300645void Context::deletePaths(GLuint first, GLsizei range)
646{
647 mResourceManager->deletePaths(first, range);
648}
649
650bool Context::hasPathData(GLuint path) const
651{
652 const auto *pathObj = mResourceManager->getPath(path);
653 if (pathObj == nullptr)
654 return false;
655
656 return pathObj->hasPathData();
657}
658
659bool Context::hasPath(GLuint path) const
660{
661 return mResourceManager->hasPath(path);
662}
663
664void Context::setPathCommands(GLuint path,
665 GLsizei numCommands,
666 const GLubyte *commands,
667 GLsizei numCoords,
668 GLenum coordType,
669 const void *coords)
670{
671 auto *pathObject = mResourceManager->getPath(path);
672
673 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
674}
675
676void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
677{
678 auto *pathObj = mResourceManager->getPath(path);
679
680 switch (pname)
681 {
682 case GL_PATH_STROKE_WIDTH_CHROMIUM:
683 pathObj->setStrokeWidth(value);
684 break;
685 case GL_PATH_END_CAPS_CHROMIUM:
686 pathObj->setEndCaps(static_cast<GLenum>(value));
687 break;
688 case GL_PATH_JOIN_STYLE_CHROMIUM:
689 pathObj->setJoinStyle(static_cast<GLenum>(value));
690 break;
691 case GL_PATH_MITER_LIMIT_CHROMIUM:
692 pathObj->setMiterLimit(value);
693 break;
694 case GL_PATH_STROKE_BOUND_CHROMIUM:
695 pathObj->setStrokeBound(value);
696 break;
697 default:
698 UNREACHABLE();
699 break;
700 }
701}
702
703void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
704{
705 const auto *pathObj = mResourceManager->getPath(path);
706
707 switch (pname)
708 {
709 case GL_PATH_STROKE_WIDTH_CHROMIUM:
710 *value = pathObj->getStrokeWidth();
711 break;
712 case GL_PATH_END_CAPS_CHROMIUM:
713 *value = static_cast<GLfloat>(pathObj->getEndCaps());
714 break;
715 case GL_PATH_JOIN_STYLE_CHROMIUM:
716 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
717 break;
718 case GL_PATH_MITER_LIMIT_CHROMIUM:
719 *value = pathObj->getMiterLimit();
720 break;
721 case GL_PATH_STROKE_BOUND_CHROMIUM:
722 *value = pathObj->getStrokeBound();
723 break;
724 default:
725 UNREACHABLE();
726 break;
727 }
728}
729
730void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
731{
732 mGLState.setPathStencilFunc(func, ref, mask);
733}
734
Jamie Madill57a89722013-07-02 11:57:03 -0400735void Context::deleteVertexArray(GLuint vertexArray)
736{
Geoff Lang36167ab2015-12-07 10:27:14 -0500737 auto iter = mVertexArrayMap.find(vertexArray);
738 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000739 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500740 VertexArray *vertexArrayObject = iter->second;
741 if (vertexArrayObject != nullptr)
742 {
743 detachVertexArray(vertexArray);
744 delete vertexArrayObject;
745 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000746
Geoff Lang36167ab2015-12-07 10:27:14 -0500747 mVertexArrayMap.erase(iter);
748 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400749 }
750}
751
Jamie Madilldc356042013-07-19 16:36:57 -0400752void Context::deleteSampler(GLuint sampler)
753{
754 if (mResourceManager->getSampler(sampler))
755 {
756 detachSampler(sampler);
757 }
758
759 mResourceManager->deleteSampler(sampler);
760}
761
Geoff Langc8058452014-02-03 12:04:11 -0500762void Context::deleteTransformFeedback(GLuint transformFeedback)
763{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500764 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500765 if (iter != mTransformFeedbackMap.end())
766 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500767 TransformFeedback *transformFeedbackObject = iter->second;
768 if (transformFeedbackObject != nullptr)
769 {
770 detachTransformFeedback(transformFeedback);
771 transformFeedbackObject->release();
772 }
773
Geoff Lang50b3fe82015-12-08 14:49:12 +0000774 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500775 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500776 }
777}
778
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000779void Context::deleteFramebuffer(GLuint framebuffer)
780{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500781 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000782
783 if (framebufferObject != mFramebufferMap.end())
784 {
785 detachFramebuffer(framebuffer);
786
787 mFramebufferHandleAllocator.release(framebufferObject->first);
788 delete framebufferObject->second;
789 mFramebufferMap.erase(framebufferObject);
790 }
791}
792
Jamie Madill33dc8432013-07-26 11:55:05 -0400793void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500795 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796
Jamie Madill33dc8432013-07-26 11:55:05 -0400797 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400799 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400801 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000802 }
803}
804
805void Context::deleteQuery(GLuint query)
806{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500807 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000808 if (queryObject != mQueryMap.end())
809 {
810 mQueryHandleAllocator.release(queryObject->first);
811 if (queryObject->second)
812 {
813 queryObject->second->release();
814 }
815 mQueryMap.erase(queryObject);
816 }
817}
818
Geoff Lang70d0f492015-12-10 17:45:46 -0500819Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820{
821 return mResourceManager->getBuffer(handle);
822}
823
Jamie Madill570f7c82014-07-03 10:38:54 -0400824Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825{
826 return mResourceManager->getTexture(handle);
827}
828
Geoff Lang70d0f492015-12-10 17:45:46 -0500829Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000830{
831 return mResourceManager->getRenderbuffer(handle);
832}
833
Jamie Madillcd055f82013-07-26 11:55:15 -0400834FenceSync *Context::getFenceSync(GLsync handle) const
835{
Minmin Gong794e0002015-04-07 18:31:54 -0700836 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400837}
838
Jamie Madill57a89722013-07-02 11:57:03 -0400839VertexArray *Context::getVertexArray(GLuint handle) const
840{
841 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500842 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400843}
844
Jamie Madilldc356042013-07-19 16:36:57 -0400845Sampler *Context::getSampler(GLuint handle) const
846{
847 return mResourceManager->getSampler(handle);
848}
849
Geoff Langc8058452014-02-03 12:04:11 -0500850TransformFeedback *Context::getTransformFeedback(GLuint handle) const
851{
Geoff Lang36167ab2015-12-07 10:27:14 -0500852 auto iter = mTransformFeedbackMap.find(handle);
853 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500854}
855
Geoff Lang70d0f492015-12-10 17:45:46 -0500856LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
857{
858 switch (identifier)
859 {
860 case GL_BUFFER:
861 return getBuffer(name);
862 case GL_SHADER:
863 return getShader(name);
864 case GL_PROGRAM:
865 return getProgram(name);
866 case GL_VERTEX_ARRAY:
867 return getVertexArray(name);
868 case GL_QUERY:
869 return getQuery(name);
870 case GL_TRANSFORM_FEEDBACK:
871 return getTransformFeedback(name);
872 case GL_SAMPLER:
873 return getSampler(name);
874 case GL_TEXTURE:
875 return getTexture(name);
876 case GL_RENDERBUFFER:
877 return getRenderbuffer(name);
878 case GL_FRAMEBUFFER:
879 return getFramebuffer(name);
880 default:
881 UNREACHABLE();
882 return nullptr;
883 }
884}
885
886LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
887{
888 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
889}
890
Martin Radev9d901792016-07-15 15:58:58 +0300891void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
892{
893 LabeledObject *object = getLabeledObject(identifier, name);
894 ASSERT(object != nullptr);
895
896 std::string labelName = GetObjectLabelFromPointer(length, label);
897 object->setLabel(labelName);
898}
899
900void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
901{
902 LabeledObject *object = getLabeledObjectFromPtr(ptr);
903 ASSERT(object != nullptr);
904
905 std::string labelName = GetObjectLabelFromPointer(length, label);
906 object->setLabel(labelName);
907}
908
909void Context::getObjectLabel(GLenum identifier,
910 GLuint name,
911 GLsizei bufSize,
912 GLsizei *length,
913 GLchar *label) const
914{
915 LabeledObject *object = getLabeledObject(identifier, name);
916 ASSERT(object != nullptr);
917
918 const std::string &objectLabel = object->getLabel();
919 GetObjectLabelBase(objectLabel, bufSize, length, label);
920}
921
922void Context::getObjectPtrLabel(const void *ptr,
923 GLsizei bufSize,
924 GLsizei *length,
925 GLchar *label) const
926{
927 LabeledObject *object = getLabeledObjectFromPtr(ptr);
928 ASSERT(object != nullptr);
929
930 const std::string &objectLabel = object->getLabel();
931 GetObjectLabelBase(objectLabel, bufSize, length, label);
932}
933
Jamie Madilldc356042013-07-19 16:36:57 -0400934bool Context::isSampler(GLuint samplerName) const
935{
936 return mResourceManager->isSampler(samplerName);
937}
938
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500939void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000940{
Jamie Madill901b3792016-05-26 09:20:40 -0400941 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700942 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000943}
944
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500945void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000946{
Jamie Madill901b3792016-05-26 09:20:40 -0400947 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700948 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000949}
950
Jamie Madilldedd7b92014-11-05 16:30:36 -0500951void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500953 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954
Jamie Madilldedd7b92014-11-05 16:30:36 -0500955 if (handle == 0)
956 {
957 texture = mZeroTextures[target].get();
958 }
959 else
960 {
Jamie Madill901b3792016-05-26 09:20:40 -0400961 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500962 }
963
964 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700965 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000966}
967
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500968void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000969{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500970 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700971 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000972}
973
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500974void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000975{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500976 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700977 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978}
979
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500980void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981{
Jamie Madill901b3792016-05-26 09:20:40 -0400982 Renderbuffer *renderbuffer =
983 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700984 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000985}
986
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500987void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400988{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500989 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700990 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400991}
992
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500993void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400994{
Geoff Lang76b10c92014-09-05 16:28:14 -0400995 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400996 Sampler *sampler =
997 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700998 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400999}
1000
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001001void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001002{
Jamie Madill901b3792016-05-26 09:20:40 -04001003 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001004 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001005}
1006
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001007void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1008 GLuint index,
1009 GLintptr offset,
1010 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001011{
Jamie Madill901b3792016-05-26 09:20:40 -04001012 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001013 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001014}
1015
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001016void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001017{
Jamie Madill901b3792016-05-26 09:20:40 -04001018 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001019 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001020}
1021
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001022void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1023 GLuint index,
1024 GLintptr offset,
1025 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001026{
Jamie Madill901b3792016-05-26 09:20:40 -04001027 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001028 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001029}
1030
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001031void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001032{
Jamie Madill901b3792016-05-26 09:20:40 -04001033 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001034 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001038{
Jamie Madill901b3792016-05-26 09:20:40 -04001039 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001040 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001041}
1042
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001043void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001044{
Jamie Madill901b3792016-05-26 09:20:40 -04001045 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001046 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001047}
1048
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001049void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001050{
Jamie Madill901b3792016-05-26 09:20:40 -04001051 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001052 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001053}
1054
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001055void Context::useProgram(GLuint program)
1056{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001057 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001061{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001062 TransformFeedback *transformFeedback =
1063 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001064 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001065}
1066
Geoff Lang5aad9672014-09-08 11:10:42 -04001067Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001069 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001070 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001071
Geoff Lang5aad9672014-09-08 11:10:42 -04001072 // begin query
1073 Error error = queryObject->begin();
1074 if (error.isError())
1075 {
1076 return error;
1077 }
1078
1079 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001080 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001081
Geoff Lang5aad9672014-09-08 11:10:42 -04001082 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001083}
1084
Geoff Lang5aad9672014-09-08 11:10:42 -04001085Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001086{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001087 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001088 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001089
Geoff Lang5aad9672014-09-08 11:10:42 -04001090 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091
Geoff Lang5aad9672014-09-08 11:10:42 -04001092 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001093 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001094
1095 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001096}
1097
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001098Error Context::queryCounter(GLuint id, GLenum target)
1099{
1100 ASSERT(target == GL_TIMESTAMP_EXT);
1101
1102 Query *queryObject = getQuery(id, true, target);
1103 ASSERT(queryObject);
1104
1105 return queryObject->queryCounter();
1106}
1107
1108void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1109{
1110 switch (pname)
1111 {
1112 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001113 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001114 break;
1115 case GL_QUERY_COUNTER_BITS_EXT:
1116 switch (target)
1117 {
1118 case GL_TIME_ELAPSED_EXT:
1119 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1120 break;
1121 case GL_TIMESTAMP_EXT:
1122 params[0] = getExtensions().queryCounterBitsTimestamp;
1123 break;
1124 default:
1125 UNREACHABLE();
1126 params[0] = 0;
1127 break;
1128 }
1129 break;
1130 default:
1131 UNREACHABLE();
1132 return;
1133 }
1134}
1135
Geoff Lang2186c382016-10-14 10:54:54 -04001136void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001137{
Geoff Lang2186c382016-10-14 10:54:54 -04001138 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001139}
1140
Geoff Lang2186c382016-10-14 10:54:54 -04001141void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001142{
Geoff Lang2186c382016-10-14 10:54:54 -04001143 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001144}
1145
Geoff Lang2186c382016-10-14 10:54:54 -04001146void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001147{
Geoff Lang2186c382016-10-14 10:54:54 -04001148 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001149}
1150
Geoff Lang2186c382016-10-14 10:54:54 -04001151void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001152{
Geoff Lang2186c382016-10-14 10:54:54 -04001153 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001154}
1155
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001156Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001157{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001158 auto framebufferIt = mFramebufferMap.find(handle);
1159 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001160}
1161
Jamie Madill33dc8432013-07-26 11:55:05 -04001162FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001163{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001164 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165
Jamie Madill33dc8432013-07-26 11:55:05 -04001166 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167 {
1168 return NULL;
1169 }
1170 else
1171 {
1172 return fence->second;
1173 }
1174}
1175
1176Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1177{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001178 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179
1180 if (query == mQueryMap.end())
1181 {
1182 return NULL;
1183 }
1184 else
1185 {
1186 if (!query->second && create)
1187 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001188 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189 query->second->addRef();
1190 }
1191 return query->second;
1192 }
1193}
1194
Geoff Lang70d0f492015-12-10 17:45:46 -05001195Query *Context::getQuery(GLuint handle) const
1196{
1197 auto iter = mQueryMap.find(handle);
1198 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1199}
1200
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001201Texture *Context::getTargetTexture(GLenum target) const
1202{
Ian Ewellbda75592016-04-18 17:25:54 -04001203 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001204 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001205}
1206
Geoff Lang76b10c92014-09-05 16:28:14 -04001207Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001208{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001209 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210}
1211
Geoff Lang492a7e42014-11-05 13:27:06 -05001212Compiler *Context::getCompiler() const
1213{
1214 return mCompiler;
1215}
1216
Jamie Madill893ab082014-05-16 16:56:10 -04001217void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218{
1219 switch (pname)
1220 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001221 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001222 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001224 mGLState.getBooleanv(pname, params);
1225 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001227}
1228
Jamie Madill893ab082014-05-16 16:56:10 -04001229void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001230{
Shannon Woods53a94a82014-06-24 15:20:36 -04001231 // Queries about context capabilities and maximums are answered by Context.
1232 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233 switch (pname)
1234 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001236 params[0] = mCaps.minAliasedLineWidth;
1237 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238 break;
1239 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001240 params[0] = mCaps.minAliasedPointSize;
1241 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001243 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001244 ASSERT(mExtensions.textureFilterAnisotropic);
1245 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001246 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001247 case GL_MAX_TEXTURE_LOD_BIAS:
1248 *params = mCaps.maxLODBias;
1249 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001250
1251 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1252 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1253 {
1254 ASSERT(mExtensions.pathRendering);
1255 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1256 memcpy(params, m, 16 * sizeof(GLfloat));
1257 }
1258 break;
1259
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001260 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001261 mGLState.getFloatv(pname, params);
1262 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001264}
1265
Jamie Madill893ab082014-05-16 16:56:10 -04001266void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267{
Shannon Woods53a94a82014-06-24 15:20:36 -04001268 // Queries about context capabilities and maximums are answered by Context.
1269 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001270
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271 switch (pname)
1272 {
Geoff Lang301d1612014-07-09 10:34:37 -04001273 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1274 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1275 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001276 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1277 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1278 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001279 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1280 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1281 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001282 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001283 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1284 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1285 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001286 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001287 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001288 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1289 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1290 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1291 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001292 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1293 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001294 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1295 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001296 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001297 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1298 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1299 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1300 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001301 case GL_MAJOR_VERSION:
1302 *params = mClientMajorVersion;
1303 break;
1304 case GL_MINOR_VERSION:
1305 *params = mClientMinorVersion;
1306 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001307 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1308 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001309 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1310 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1311 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001312 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1313 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1314 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001315 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001316 case GL_MAX_VIEWPORT_DIMS:
1317 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001318 params[0] = mCaps.maxViewportWidth;
1319 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001320 }
1321 break;
1322 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001323 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001325 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1326 *params = mResetStrategy;
1327 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001328 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001329 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001331 case GL_SHADER_BINARY_FORMATS:
1332 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1333 break;
1334 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001335 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001336 break;
1337 case GL_PROGRAM_BINARY_FORMATS:
1338 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001339 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001340 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001341 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001342 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001343
1344 // GL_KHR_debug
1345 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1346 *params = mExtensions.maxDebugMessageLength;
1347 break;
1348 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1349 *params = mExtensions.maxDebugLoggedMessages;
1350 break;
1351 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1352 *params = mExtensions.maxDebugGroupStackDepth;
1353 break;
1354 case GL_MAX_LABEL_LENGTH:
1355 *params = mExtensions.maxLabelLength;
1356 break;
1357
Ian Ewell53f59f42016-01-28 17:36:55 -05001358 // GL_EXT_disjoint_timer_query
1359 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001360 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001361 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001362 case GL_MAX_FRAMEBUFFER_WIDTH:
1363 *params = mCaps.maxFramebufferWidth;
1364 break;
1365 case GL_MAX_FRAMEBUFFER_HEIGHT:
1366 *params = mCaps.maxFramebufferHeight;
1367 break;
1368 case GL_MAX_FRAMEBUFFER_SAMPLES:
1369 *params = mCaps.maxFramebufferSamples;
1370 break;
1371 case GL_MAX_SAMPLE_MASK_WORDS:
1372 *params = mCaps.maxSampleMaskWords;
1373 break;
1374 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1375 *params = mCaps.maxColorTextureSamples;
1376 break;
1377 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1378 *params = mCaps.maxDepthTextureSamples;
1379 break;
1380 case GL_MAX_INTEGER_SAMPLES:
1381 *params = mCaps.maxIntegerSamples;
1382 break;
1383 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1384 *params = mCaps.maxVertexAttribRelativeOffset;
1385 break;
1386 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1387 *params = mCaps.maxVertexAttribBindings;
1388 break;
1389 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1390 *params = mCaps.maxVertexAttribStride;
1391 break;
1392 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1393 *params = mCaps.maxVertexAtomicCounterBuffers;
1394 break;
1395 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1396 *params = mCaps.maxVertexAtomicCounters;
1397 break;
1398 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1399 *params = mCaps.maxVertexImageUniforms;
1400 break;
1401 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1402 *params = mCaps.maxVertexShaderStorageBlocks;
1403 break;
1404 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1405 *params = mCaps.maxFragmentAtomicCounterBuffers;
1406 break;
1407 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1408 *params = mCaps.maxFragmentAtomicCounters;
1409 break;
1410 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1411 *params = mCaps.maxFragmentImageUniforms;
1412 break;
1413 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1414 *params = mCaps.maxFragmentShaderStorageBlocks;
1415 break;
1416 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1417 *params = mCaps.minProgramTextureGatherOffset;
1418 break;
1419 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1420 *params = mCaps.maxProgramTextureGatherOffset;
1421 break;
1422 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1423 *params = mCaps.maxComputeWorkGroupInvocations;
1424 break;
1425 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1426 *params = mCaps.maxComputeUniformBlocks;
1427 break;
1428 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1429 *params = mCaps.maxComputeTextureImageUnits;
1430 break;
1431 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1432 *params = mCaps.maxComputeSharedMemorySize;
1433 break;
1434 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1435 *params = mCaps.maxComputeUniformComponents;
1436 break;
1437 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1438 *params = mCaps.maxComputeAtomicCounterBuffers;
1439 break;
1440 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1441 *params = mCaps.maxComputeAtomicCounters;
1442 break;
1443 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1444 *params = mCaps.maxComputeImageUniforms;
1445 break;
1446 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1447 *params = mCaps.maxCombinedComputeUniformComponents;
1448 break;
1449 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1450 *params = mCaps.maxComputeShaderStorageBlocks;
1451 break;
1452 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1453 *params = mCaps.maxCombinedShaderOutputResources;
1454 break;
1455 case GL_MAX_UNIFORM_LOCATIONS:
1456 *params = mCaps.maxUniformLocations;
1457 break;
1458 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1459 *params = mCaps.maxAtomicCounterBufferBindings;
1460 break;
1461 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1462 *params = mCaps.maxAtomicCounterBufferSize;
1463 break;
1464 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1465 *params = mCaps.maxCombinedAtomicCounterBuffers;
1466 break;
1467 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1468 *params = mCaps.maxCombinedAtomicCounters;
1469 break;
1470 case GL_MAX_IMAGE_UNITS:
1471 *params = mCaps.maxImageUnits;
1472 break;
1473 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1474 *params = mCaps.maxCombinedImageUniforms;
1475 break;
1476 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1477 *params = mCaps.maxShaderStorageBufferBindings;
1478 break;
1479 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1480 *params = mCaps.maxCombinedShaderStorageBlocks;
1481 break;
1482 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1483 *params = mCaps.shaderStorageBufferOffsetAlignment;
1484 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001485 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001486 mGLState.getIntegerv(mState, pname, params);
1487 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001488 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001489}
1490
Jamie Madill893ab082014-05-16 16:56:10 -04001491void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001492{
Shannon Woods53a94a82014-06-24 15:20:36 -04001493 // Queries about context capabilities and maximums are answered by Context.
1494 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001495 switch (pname)
1496 {
1497 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001498 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001499 break;
1500 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001501 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001502 break;
1503 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001504 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001505 break;
1506 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001507 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001508 break;
1509 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001510 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001511 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001512
1513 // GL_EXT_disjoint_timer_query
1514 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001515 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001516 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001517
1518 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1519 *params = mCaps.maxShaderStorageBlockSize;
1520 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001521 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001522 UNREACHABLE();
1523 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001524 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001525}
1526
Geoff Lang70d0f492015-12-10 17:45:46 -05001527void Context::getPointerv(GLenum pname, void **params) const
1528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001529 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001530}
1531
Martin Radev66fb8202016-07-28 11:45:20 +03001532void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001533{
Shannon Woods53a94a82014-06-24 15:20:36 -04001534 // Queries about context capabilities and maximums are answered by Context.
1535 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001536
1537 GLenum nativeType;
1538 unsigned int numParams;
1539 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001540 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001541 ASSERT(queryStatus);
1542
1543 if (nativeType == GL_INT)
1544 {
1545 switch (target)
1546 {
1547 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1548 ASSERT(index < 3u);
1549 *data = mCaps.maxComputeWorkGroupCount[index];
1550 break;
1551 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1552 ASSERT(index < 3u);
1553 *data = mCaps.maxComputeWorkGroupSize[index];
1554 break;
1555 default:
1556 mGLState.getIntegeri_v(target, index, data);
1557 }
1558 }
1559 else
1560 {
1561 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1562 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001563}
1564
Martin Radev66fb8202016-07-28 11:45:20 +03001565void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001566{
Shannon Woods53a94a82014-06-24 15:20:36 -04001567 // Queries about context capabilities and maximums are answered by Context.
1568 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001569
1570 GLenum nativeType;
1571 unsigned int numParams;
1572 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001573 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001574 ASSERT(queryStatus);
1575
1576 if (nativeType == GL_INT_64_ANGLEX)
1577 {
1578 mGLState.getInteger64i_v(target, index, data);
1579 }
1580 else
1581 {
1582 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1583 }
1584}
1585
1586void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1587{
1588 // Queries about context capabilities and maximums are answered by Context.
1589 // Queries about current GL state values are answered by State.
1590
1591 GLenum nativeType;
1592 unsigned int numParams;
1593 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001594 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001595 ASSERT(queryStatus);
1596
1597 if (nativeType == GL_BOOL)
1598 {
1599 mGLState.getBooleani_v(target, index, data);
1600 }
1601 else
1602 {
1603 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1604 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001605}
1606
Geoff Langf6db0982015-08-25 13:04:00 -04001607Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001608{
Jamie Madill1b94d432015-08-07 13:23:23 -04001609 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001610 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001611 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001612
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001613 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001614}
1615
Geoff Langf6db0982015-08-25 13:04:00 -04001616Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1617{
1618 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001619 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001620 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001621
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001622 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001623}
1624
1625Error Context::drawElements(GLenum mode,
1626 GLsizei count,
1627 GLenum type,
1628 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001629 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001630{
Jamie Madill1b94d432015-08-07 13:23:23 -04001631 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001632 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001633}
1634
1635Error Context::drawElementsInstanced(GLenum mode,
1636 GLsizei count,
1637 GLenum type,
1638 const GLvoid *indices,
1639 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001640 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001641{
1642 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001643 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1644 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001645}
1646
1647Error Context::drawRangeElements(GLenum mode,
1648 GLuint start,
1649 GLuint end,
1650 GLsizei count,
1651 GLenum type,
1652 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001653 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001654{
1655 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001656 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001657}
1658
Geoff Lang129753a2015-01-09 16:52:09 -05001659Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001660{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001661 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001662}
1663
1664Error Context::finish()
1665{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001666 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001667}
1668
Austin Kinross6ee1e782015-05-29 17:05:37 -07001669void Context::insertEventMarker(GLsizei length, const char *marker)
1670{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001671 ASSERT(mImplementation);
1672 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001673}
1674
1675void Context::pushGroupMarker(GLsizei length, const char *marker)
1676{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001677 ASSERT(mImplementation);
1678 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001679}
1680
1681void Context::popGroupMarker()
1682{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001683 ASSERT(mImplementation);
1684 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001685}
1686
Geoff Langd8605522016-04-13 10:19:12 -04001687void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1688{
1689 Program *programObject = getProgram(program);
1690 ASSERT(programObject);
1691
1692 programObject->bindUniformLocation(location, name);
1693}
1694
Sami Väisänena797e062016-05-12 15:23:40 +03001695void Context::setCoverageModulation(GLenum components)
1696{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001697 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001698}
1699
Sami Väisänene45e53b2016-05-25 10:36:04 +03001700void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1701{
1702 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1703}
1704
1705void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1706{
1707 GLfloat I[16];
1708 angle::Matrix<GLfloat>::setToIdentity(I);
1709
1710 mGLState.loadPathRenderingMatrix(matrixMode, I);
1711}
1712
1713void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1714{
1715 const auto *pathObj = mResourceManager->getPath(path);
1716 if (!pathObj)
1717 return;
1718
1719 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1720 syncRendererState();
1721
1722 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1723}
1724
1725void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1726{
1727 const auto *pathObj = mResourceManager->getPath(path);
1728 if (!pathObj)
1729 return;
1730
1731 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1732 syncRendererState();
1733
1734 mImplementation->stencilStrokePath(pathObj, reference, mask);
1735}
1736
1737void Context::coverFillPath(GLuint path, GLenum coverMode)
1738{
1739 const auto *pathObj = mResourceManager->getPath(path);
1740 if (!pathObj)
1741 return;
1742
1743 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1744 syncRendererState();
1745
1746 mImplementation->coverFillPath(pathObj, coverMode);
1747}
1748
1749void Context::coverStrokePath(GLuint path, GLenum coverMode)
1750{
1751 const auto *pathObj = mResourceManager->getPath(path);
1752 if (!pathObj)
1753 return;
1754
1755 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1756 syncRendererState();
1757
1758 mImplementation->coverStrokePath(pathObj, coverMode);
1759}
1760
1761void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1762{
1763 const auto *pathObj = mResourceManager->getPath(path);
1764 if (!pathObj)
1765 return;
1766
1767 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1768 syncRendererState();
1769
1770 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1771}
1772
1773void Context::stencilThenCoverStrokePath(GLuint path,
1774 GLint reference,
1775 GLuint mask,
1776 GLenum coverMode)
1777{
1778 const auto *pathObj = mResourceManager->getPath(path);
1779 if (!pathObj)
1780 return;
1781
1782 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1783 syncRendererState();
1784
1785 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1786}
1787
Sami Väisänend59ca052016-06-21 16:10:00 +03001788void Context::coverFillPathInstanced(GLsizei numPaths,
1789 GLenum pathNameType,
1790 const void *paths,
1791 GLuint pathBase,
1792 GLenum coverMode,
1793 GLenum transformType,
1794 const GLfloat *transformValues)
1795{
1796 const auto &pathObjects =
1797 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1798
1799 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1800 syncRendererState();
1801
1802 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1803}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001804
Sami Väisänend59ca052016-06-21 16:10:00 +03001805void Context::coverStrokePathInstanced(GLsizei numPaths,
1806 GLenum pathNameType,
1807 const void *paths,
1808 GLuint pathBase,
1809 GLenum coverMode,
1810 GLenum transformType,
1811 const GLfloat *transformValues)
1812{
1813 const auto &pathObjects =
1814 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1815
1816 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1817 syncRendererState();
1818
1819 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1820 transformValues);
1821}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001822
Sami Väisänend59ca052016-06-21 16:10:00 +03001823void Context::stencilFillPathInstanced(GLsizei numPaths,
1824 GLenum pathNameType,
1825 const void *paths,
1826 GLuint pathBase,
1827 GLenum fillMode,
1828 GLuint mask,
1829 GLenum transformType,
1830 const GLfloat *transformValues)
1831{
1832 const auto &pathObjects =
1833 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1834
1835 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1836 syncRendererState();
1837
1838 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1839 transformValues);
1840}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001841
Sami Väisänend59ca052016-06-21 16:10:00 +03001842void Context::stencilStrokePathInstanced(GLsizei numPaths,
1843 GLenum pathNameType,
1844 const void *paths,
1845 GLuint pathBase,
1846 GLint reference,
1847 GLuint mask,
1848 GLenum transformType,
1849 const GLfloat *transformValues)
1850{
1851 const auto &pathObjects =
1852 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1853
1854 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1855 syncRendererState();
1856
1857 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1858 transformValues);
1859}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001860
Sami Väisänend59ca052016-06-21 16:10:00 +03001861void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1862 GLenum pathNameType,
1863 const void *paths,
1864 GLuint pathBase,
1865 GLenum fillMode,
1866 GLuint mask,
1867 GLenum coverMode,
1868 GLenum transformType,
1869 const GLfloat *transformValues)
1870{
1871 const auto &pathObjects =
1872 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1873
1874 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1875 syncRendererState();
1876
1877 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1878 transformType, transformValues);
1879}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001880
Sami Väisänend59ca052016-06-21 16:10:00 +03001881void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1882 GLenum pathNameType,
1883 const void *paths,
1884 GLuint pathBase,
1885 GLint reference,
1886 GLuint mask,
1887 GLenum coverMode,
1888 GLenum transformType,
1889 const GLfloat *transformValues)
1890{
1891 const auto &pathObjects =
1892 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1893
1894 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1895 syncRendererState();
1896
1897 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1898 transformType, transformValues);
1899}
1900
Sami Väisänen46eaa942016-06-29 10:26:37 +03001901void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1902{
1903 auto *programObject = getProgram(program);
1904
1905 programObject->bindFragmentInputLocation(location, name);
1906}
1907
1908void Context::programPathFragmentInputGen(GLuint program,
1909 GLint location,
1910 GLenum genMode,
1911 GLint components,
1912 const GLfloat *coeffs)
1913{
1914 auto *programObject = getProgram(program);
1915
1916 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1917}
1918
Jamie Madill437fa652016-05-03 15:13:24 -04001919void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001920{
Geoff Langda5777c2014-07-11 09:52:58 -04001921 if (error.isError())
1922 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001923 GLenum code = error.getCode();
1924 mErrors.insert(code);
1925 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1926 {
1927 markContextLost();
1928 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001929
1930 if (!error.getMessage().empty())
1931 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001932 auto *debug = &mGLState.getDebug();
1933 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1934 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001935 }
Geoff Langda5777c2014-07-11 09:52:58 -04001936 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001937}
1938
1939// Get one of the recorded errors and clear its flag, if any.
1940// [OpenGL ES 2.0.24] section 2.5 page 13.
1941GLenum Context::getError()
1942{
Geoff Langda5777c2014-07-11 09:52:58 -04001943 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001944 {
Geoff Langda5777c2014-07-11 09:52:58 -04001945 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001946 }
Geoff Langda5777c2014-07-11 09:52:58 -04001947 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001948 {
Geoff Langda5777c2014-07-11 09:52:58 -04001949 GLenum error = *mErrors.begin();
1950 mErrors.erase(mErrors.begin());
1951 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001952 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001953}
1954
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001955// NOTE: this function should not assume that this context is current!
1956void Context::markContextLost()
1957{
1958 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001959 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001960 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001961 mContextLostForced = true;
1962 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001963 mContextLost = true;
1964}
1965
1966bool Context::isContextLost()
1967{
1968 return mContextLost;
1969}
1970
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001971GLenum Context::getResetStatus()
1972{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001973 // Even if the application doesn't want to know about resets, we want to know
1974 // as it will allow us to skip all the calls.
1975 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001976 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001977 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001978 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001979 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001980 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001981
1982 // EXT_robustness, section 2.6: If the reset notification behavior is
1983 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1984 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1985 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001986 }
1987
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001988 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1989 // status should be returned at least once, and GL_NO_ERROR should be returned
1990 // once the device has finished resetting.
1991 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001992 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001993 ASSERT(mResetStatus == GL_NO_ERROR);
1994 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001995
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001996 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001997 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001998 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001999 }
2000 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002001 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002002 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002003 // If markContextLost was used to mark the context lost then
2004 // assume that is not recoverable, and continue to report the
2005 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002006 mResetStatus = mImplementation->getResetStatus();
2007 }
Jamie Madill893ab082014-05-16 16:56:10 -04002008
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002009 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002010}
2011
2012bool Context::isResetNotificationEnabled()
2013{
2014 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2015}
2016
Corentin Walleze3b10e82015-05-20 11:06:25 -04002017const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002018{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002019 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002020}
2021
2022EGLenum Context::getClientType() const
2023{
2024 return mClientType;
2025}
2026
2027EGLenum Context::getRenderBuffer() const
2028{
Corentin Wallez37c39792015-08-20 14:19:46 -04002029 auto framebufferIt = mFramebufferMap.find(0);
2030 if (framebufferIt != mFramebufferMap.end())
2031 {
2032 const Framebuffer *framebuffer = framebufferIt->second;
2033 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2034
2035 ASSERT(backAttachment != nullptr);
2036 return backAttachment->getSurface()->getRenderBuffer();
2037 }
2038 else
2039 {
2040 return EGL_NONE;
2041 }
Régis Fénéon83107972015-02-05 12:57:44 +01002042}
2043
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002044VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002045{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002046 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002047 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2048 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002049 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002050 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2051
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002052 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002053 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002054
2055 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002056}
2057
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002058TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002059{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002060 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002061 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2062 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002063 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002064 transformFeedback =
2065 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002066 transformFeedback->addRef();
2067 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002068 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002069
2070 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002071}
2072
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002073Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2074{
2075 // Can be called from Bind without a prior call to Gen.
2076 auto framebufferIt = mFramebufferMap.find(framebuffer);
2077 bool neverCreated = framebufferIt == mFramebufferMap.end();
2078 if (neverCreated || framebufferIt->second == nullptr)
2079 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002080 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002081 if (neverCreated)
2082 {
2083 mFramebufferHandleAllocator.reserve(framebuffer);
2084 mFramebufferMap[framebuffer] = newFBO;
2085 return newFBO;
2086 }
2087
2088 framebufferIt->second = newFBO;
2089 }
2090
2091 return framebufferIt->second;
2092}
2093
Geoff Langf41a7152016-09-19 15:11:17 -04002094bool Context::isTextureGenerated(GLuint texture) const
2095{
2096 return mResourceManager->isTextureGenerated(texture);
2097}
2098
2099bool Context::isBufferGenerated(GLuint buffer) const
2100{
2101 return mResourceManager->isBufferGenerated(buffer);
2102}
2103
2104bool Context::isRenderbufferGenerated(GLuint renderbuffer) const
2105{
2106 return mResourceManager->isRenderbufferGenerated(renderbuffer);
2107}
2108
2109bool Context::isFramebufferGenerated(GLuint framebuffer) const
2110{
2111 ASSERT(mFramebufferMap.find(0) != mFramebufferMap.end());
2112 return mFramebufferMap.find(framebuffer) != mFramebufferMap.end();
2113}
2114
Geoff Lang36167ab2015-12-07 10:27:14 -05002115bool Context::isVertexArrayGenerated(GLuint vertexArray)
2116{
Geoff Langf41a7152016-09-19 15:11:17 -04002117 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002118 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2119}
2120
2121bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2122{
Geoff Langf41a7152016-09-19 15:11:17 -04002123 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002124 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2125}
2126
Shannon Woods53a94a82014-06-24 15:20:36 -04002127void Context::detachTexture(GLuint texture)
2128{
2129 // Simple pass-through to State's detachTexture method, as textures do not require
2130 // allocation map management either here or in the resource manager at detach time.
2131 // Zero textures are held by the Context, and we don't attempt to request them from
2132 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002133 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002134}
2135
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002136void Context::detachBuffer(GLuint buffer)
2137{
Yuly Novikov5807a532015-12-03 13:01:22 -05002138 // Simple pass-through to State's detachBuffer method, since
2139 // only buffer attachments to container objects that are bound to the current context
2140 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002141
Yuly Novikov5807a532015-12-03 13:01:22 -05002142 // [OpenGL ES 3.2] section 5.1.2 page 45:
2143 // Attachments to unbound container objects, such as
2144 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2145 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002146 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002147}
2148
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002149void Context::detachFramebuffer(GLuint framebuffer)
2150{
Shannon Woods53a94a82014-06-24 15:20:36 -04002151 // Framebuffer detachment is handled by Context, because 0 is a valid
2152 // Framebuffer object, and a pointer to it must be passed from Context
2153 // to State at binding time.
2154
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002155 // [OpenGL ES 2.0.24] section 4.4 page 107:
2156 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2157 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2158
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002159 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002160 {
2161 bindReadFramebuffer(0);
2162 }
2163
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002164 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002165 {
2166 bindDrawFramebuffer(0);
2167 }
2168}
2169
2170void Context::detachRenderbuffer(GLuint renderbuffer)
2171{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002172 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002173}
2174
Jamie Madill57a89722013-07-02 11:57:03 -04002175void Context::detachVertexArray(GLuint vertexArray)
2176{
Jamie Madill77a72f62015-04-14 11:18:32 -04002177 // Vertex array detachment is handled by Context, because 0 is a valid
2178 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002179 // binding time.
2180
Jamie Madill57a89722013-07-02 11:57:03 -04002181 // [OpenGL ES 3.0.2] section 2.10 page 43:
2182 // If a vertex array object that is currently bound is deleted, the binding
2183 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002184 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002185 {
2186 bindVertexArray(0);
2187 }
2188}
2189
Geoff Langc8058452014-02-03 12:04:11 -05002190void Context::detachTransformFeedback(GLuint transformFeedback)
2191{
Corentin Walleza2257da2016-04-19 16:43:12 -04002192 // Transform feedback detachment is handled by Context, because 0 is a valid
2193 // transform feedback, and a pointer to it must be passed from Context to State at
2194 // binding time.
2195
2196 // The OpenGL specification doesn't mention what should happen when the currently bound
2197 // transform feedback object is deleted. Since it is a container object, we treat it like
2198 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002199 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002200 {
2201 bindTransformFeedback(0);
2202 }
Geoff Langc8058452014-02-03 12:04:11 -05002203}
2204
Jamie Madilldc356042013-07-19 16:36:57 -04002205void Context::detachSampler(GLuint sampler)
2206{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002207 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002208}
2209
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002210void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002212 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002213}
2214
Jamie Madille29d1672013-07-19 16:36:57 -04002215void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2216{
Geoff Langc1984ed2016-10-07 12:41:00 -04002217 Sampler *samplerObject =
2218 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2219 SetSamplerParameteri(samplerObject, pname, param);
2220}
Jamie Madille29d1672013-07-19 16:36:57 -04002221
Geoff Langc1984ed2016-10-07 12:41:00 -04002222void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2223{
2224 Sampler *samplerObject =
2225 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2226 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002227}
2228
2229void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2230{
Geoff Langc1984ed2016-10-07 12:41:00 -04002231 Sampler *samplerObject =
2232 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2233 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002234}
2235
Geoff Langc1984ed2016-10-07 12:41:00 -04002236void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002237{
Geoff Langc1984ed2016-10-07 12:41:00 -04002238 Sampler *samplerObject =
2239 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2240 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002241}
2242
Geoff Langc1984ed2016-10-07 12:41:00 -04002243void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002244{
Geoff Langc1984ed2016-10-07 12:41:00 -04002245 const Sampler *samplerObject =
2246 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2247 QuerySamplerParameteriv(samplerObject, pname, params);
2248}
Jamie Madill9675b802013-07-19 16:36:59 -04002249
Geoff Langc1984ed2016-10-07 12:41:00 -04002250void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2251{
2252 const Sampler *samplerObject =
2253 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2254 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002255}
2256
Olli Etuahof0fee072016-03-30 15:11:58 +03002257void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2258{
2259 gl::Program *programObject = getProgram(program);
2260 ASSERT(programObject != nullptr);
2261
2262 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2263 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2264}
2265
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002266void Context::initRendererString()
2267{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002268 std::ostringstream rendererString;
2269 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002270 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002271 rendererString << ")";
2272
Geoff Langcec35902014-04-16 10:52:36 -04002273 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002274}
2275
Geoff Langc287ea62016-09-16 14:46:51 -04002276const char *Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002277{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002278 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002279}
2280
Geoff Langcec35902014-04-16 10:52:36 -04002281void Context::initExtensionStrings()
2282{
Geoff Langc287ea62016-09-16 14:46:51 -04002283 for (const auto &extensionString : mExtensions.getStrings())
2284 {
2285 mExtensionStrings.push_back(MakeStaticString(extensionString));
2286 }
Geoff Langcec35902014-04-16 10:52:36 -04002287
Geoff Langc0b9ef42014-07-02 10:02:37 -04002288 std::ostringstream combinedStringStream;
Geoff Langc287ea62016-09-16 14:46:51 -04002289 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(),
2290 std::ostream_iterator<const char *>(combinedStringStream, " "));
2291 mExtensionString = MakeStaticString(combinedStringStream.str());
Geoff Langcec35902014-04-16 10:52:36 -04002292}
2293
Geoff Langc287ea62016-09-16 14:46:51 -04002294const char *Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002295{
2296 return mExtensionString;
2297}
2298
Geoff Langc287ea62016-09-16 14:46:51 -04002299const char *Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002300{
2301 return mExtensionStrings[idx];
2302}
2303
2304size_t Context::getExtensionStringCount() const
2305{
2306 return mExtensionStrings.size();
2307}
2308
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002309void Context::beginTransformFeedback(GLenum primitiveMode)
2310{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002311 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002312 ASSERT(transformFeedback != nullptr);
2313 ASSERT(!transformFeedback->isPaused());
2314
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002315 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002316}
2317
2318bool Context::hasActiveTransformFeedback(GLuint program) const
2319{
2320 for (auto pair : mTransformFeedbackMap)
2321 {
2322 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2323 {
2324 return true;
2325 }
2326 }
2327 return false;
2328}
2329
Geoff Langc287ea62016-09-16 14:46:51 -04002330void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002331{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002332 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002333
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002334 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002335
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002336 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002337
Martin Radev1be913c2016-07-11 17:59:16 +03002338 if (mClientMajorVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002339 {
2340 // Disable ES3+ extensions
2341 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002342 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002343 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002344 }
2345
Martin Radev1be913c2016-07-11 17:59:16 +03002346 if (mClientMajorVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002347 {
2348 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2349 //mExtensions.sRGB = false;
2350 }
2351
Jamie Madill00ed7a12016-05-19 13:13:38 -04002352 // Some extensions are always available because they are implemented in the GL layer.
2353 mExtensions.bindUniformLocation = true;
2354 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002355 mExtensions.bindGeneratesResource = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002356
2357 // Enable the no error extension if the context was created with the flag.
2358 mExtensions.noError = mSkipValidation;
2359
Geoff Lang70d0f492015-12-10 17:45:46 -05002360 // Explicitly enable GL_KHR_debug
2361 mExtensions.debug = true;
2362 mExtensions.maxDebugMessageLength = 1024;
2363 mExtensions.maxDebugLoggedMessages = 1024;
2364 mExtensions.maxDebugGroupStackDepth = 1024;
2365 mExtensions.maxLabelLength = 1024;
2366
Geoff Langff5b2d52016-09-07 11:32:23 -04002367 // Explicitly enable GL_ANGLE_robust_client_memory
2368 mExtensions.robustClientMemory = true;
2369
Geoff Lang301d1612014-07-09 10:34:37 -04002370 // Apply implementation limits
2371 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002372 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2373 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2374
2375 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002376
Geoff Langc287ea62016-09-16 14:46:51 -04002377 // WebGL compatibility
2378 mExtensions.webglCompatibility = webGLContext;
2379 for (const auto &extensionInfo : GetExtensionInfoMap())
2380 {
2381 // If this context is for WebGL, disable all enableable extensions
2382 if (webGLContext && extensionInfo.second.Enableable)
2383 {
2384 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2385 }
2386 }
2387
2388 // Generate texture caps
2389 updateCaps();
2390}
2391
2392void Context::updateCaps()
2393{
Geoff Lang900013c2014-07-07 11:32:19 -04002394 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002395 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002396
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002397 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002398 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2399 {
2400 GLenum format = i->first;
2401 TextureCaps formatCaps = i->second;
2402
Geoff Lang5d601382014-07-22 15:14:06 -04002403 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002404
Geoff Lang0d8b7242015-09-09 14:56:53 -04002405 // Update the format caps based on the client version and extensions.
2406 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2407 // ES3.
2408 formatCaps.texturable =
Martin Radev1be913c2016-07-11 17:59:16 +03002409 formatCaps.texturable && formatInfo.textureSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002410 formatCaps.renderable =
Martin Radev1be913c2016-07-11 17:59:16 +03002411 formatCaps.renderable && formatInfo.renderSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002412 formatCaps.filterable =
Martin Radev1be913c2016-07-11 17:59:16 +03002413 formatCaps.filterable && formatInfo.filterSupport(mClientMajorVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002414
2415 // OpenGL ES does not support multisampling with integer formats
2416 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002417 {
Geoff Langd87878e2014-09-19 15:42:59 -04002418 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002419 }
Geoff Langd87878e2014-09-19 15:42:59 -04002420
2421 if (formatCaps.texturable && formatInfo.compressed)
2422 {
2423 mCaps.compressedTextureFormats.push_back(format);
2424 }
2425
2426 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002427 }
2428}
2429
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002430void Context::initWorkarounds()
2431{
2432 // Lose the context upon out of memory error if the application is
2433 // expecting to watch for those events.
2434 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2435}
2436
Jamie Madill1b94d432015-08-07 13:23:23 -04002437void Context::syncRendererState()
2438{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002439 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2440 mImplementation->syncState(mGLState, dirtyBits);
2441 mGLState.clearDirtyBits();
2442 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002443}
2444
Jamie Madillad9f24e2016-02-12 09:27:24 -05002445void Context::syncRendererState(const State::DirtyBits &bitMask,
2446 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002447{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002448 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2449 mImplementation->syncState(mGLState, dirtyBits);
2450 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002451
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002452 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002453}
Jamie Madillc29968b2016-01-20 11:17:23 -05002454
2455void Context::blitFramebuffer(GLint srcX0,
2456 GLint srcY0,
2457 GLint srcX1,
2458 GLint srcY1,
2459 GLint dstX0,
2460 GLint dstY0,
2461 GLint dstX1,
2462 GLint dstY1,
2463 GLbitfield mask,
2464 GLenum filter)
2465{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002466 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002467 ASSERT(drawFramebuffer);
2468
2469 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2470 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2471
Jamie Madillad9f24e2016-02-12 09:27:24 -05002472 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002473
Jamie Madill8415b5f2016-04-26 13:41:39 -04002474 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002475}
Jamie Madillc29968b2016-01-20 11:17:23 -05002476
2477void Context::clear(GLbitfield mask)
2478{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002479 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002480 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002481}
2482
2483void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2484{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002485 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002486 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2487 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002488}
2489
2490void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2491{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002492 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002493 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2494 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002495}
2496
2497void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2498{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002499 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002500 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2501 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002502}
2503
2504void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2505{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002506 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002507 ASSERT(framebufferObject);
2508
2509 // If a buffer is not present, the clear has no effect
2510 if (framebufferObject->getDepthbuffer() == nullptr &&
2511 framebufferObject->getStencilbuffer() == nullptr)
2512 {
2513 return;
2514 }
2515
Jamie Madillad9f24e2016-02-12 09:27:24 -05002516 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002517 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2518 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002519}
2520
2521void Context::readPixels(GLint x,
2522 GLint y,
2523 GLsizei width,
2524 GLsizei height,
2525 GLenum format,
2526 GLenum type,
2527 GLvoid *pixels)
2528{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002529 if (width == 0 || height == 0)
2530 {
2531 return;
2532 }
2533
Jamie Madillad9f24e2016-02-12 09:27:24 -05002534 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002535
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002536 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002537 ASSERT(framebufferObject);
2538
2539 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002540 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002541}
2542
2543void Context::copyTexImage2D(GLenum target,
2544 GLint level,
2545 GLenum internalformat,
2546 GLint x,
2547 GLint y,
2548 GLsizei width,
2549 GLsizei height,
2550 GLint border)
2551{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002552 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002553 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002554
Jamie Madillc29968b2016-01-20 11:17:23 -05002555 Rectangle sourceArea(x, y, width, height);
2556
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002557 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002558 Texture *texture =
2559 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002560 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002561}
2562
2563void Context::copyTexSubImage2D(GLenum target,
2564 GLint level,
2565 GLint xoffset,
2566 GLint yoffset,
2567 GLint x,
2568 GLint y,
2569 GLsizei width,
2570 GLsizei height)
2571{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002572 if (width == 0 || height == 0)
2573 {
2574 return;
2575 }
2576
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002577 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002578 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002579
Jamie Madillc29968b2016-01-20 11:17:23 -05002580 Offset destOffset(xoffset, yoffset, 0);
2581 Rectangle sourceArea(x, y, width, height);
2582
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002583 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002584 Texture *texture =
2585 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002586 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002587}
2588
2589void Context::copyTexSubImage3D(GLenum target,
2590 GLint level,
2591 GLint xoffset,
2592 GLint yoffset,
2593 GLint zoffset,
2594 GLint x,
2595 GLint y,
2596 GLsizei width,
2597 GLsizei height)
2598{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002599 if (width == 0 || height == 0)
2600 {
2601 return;
2602 }
2603
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002604 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002605 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002606
Jamie Madillc29968b2016-01-20 11:17:23 -05002607 Offset destOffset(xoffset, yoffset, zoffset);
2608 Rectangle sourceArea(x, y, width, height);
2609
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002610 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002611 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002612 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002613}
2614
2615void Context::framebufferTexture2D(GLenum target,
2616 GLenum attachment,
2617 GLenum textarget,
2618 GLuint texture,
2619 GLint level)
2620{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002621 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002622 ASSERT(framebuffer);
2623
2624 if (texture != 0)
2625 {
2626 Texture *textureObj = getTexture(texture);
2627
2628 ImageIndex index = ImageIndex::MakeInvalid();
2629
2630 if (textarget == GL_TEXTURE_2D)
2631 {
2632 index = ImageIndex::Make2D(level);
2633 }
2634 else
2635 {
2636 ASSERT(IsCubeMapTextureTarget(textarget));
2637 index = ImageIndex::MakeCube(textarget, level);
2638 }
2639
2640 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2641 }
2642 else
2643 {
2644 framebuffer->resetAttachment(attachment);
2645 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002646
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002647 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002648}
2649
2650void Context::framebufferRenderbuffer(GLenum target,
2651 GLenum attachment,
2652 GLenum renderbuffertarget,
2653 GLuint renderbuffer)
2654{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002655 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002656 ASSERT(framebuffer);
2657
2658 if (renderbuffer != 0)
2659 {
2660 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2661 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2662 renderbufferObject);
2663 }
2664 else
2665 {
2666 framebuffer->resetAttachment(attachment);
2667 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002668
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002669 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002670}
2671
2672void Context::framebufferTextureLayer(GLenum target,
2673 GLenum attachment,
2674 GLuint texture,
2675 GLint level,
2676 GLint layer)
2677{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002678 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002679 ASSERT(framebuffer);
2680
2681 if (texture != 0)
2682 {
2683 Texture *textureObject = getTexture(texture);
2684
2685 ImageIndex index = ImageIndex::MakeInvalid();
2686
2687 if (textureObject->getTarget() == GL_TEXTURE_3D)
2688 {
2689 index = ImageIndex::Make3D(level, layer);
2690 }
2691 else
2692 {
2693 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2694 index = ImageIndex::Make2DArray(level, layer);
2695 }
2696
2697 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2698 }
2699 else
2700 {
2701 framebuffer->resetAttachment(attachment);
2702 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002703
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002704 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002705}
2706
2707void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2708{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002709 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002710 ASSERT(framebuffer);
2711 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002712 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002713}
2714
2715void Context::readBuffer(GLenum mode)
2716{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002717 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002718 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002719 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002720}
2721
2722void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2723{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002724 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002725 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002726
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002727 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002728 ASSERT(framebuffer);
2729
2730 // The specification isn't clear what should be done when the framebuffer isn't complete.
2731 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002732 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002733}
2734
2735void Context::invalidateFramebuffer(GLenum target,
2736 GLsizei numAttachments,
2737 const GLenum *attachments)
2738{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002739 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002740 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002741
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002742 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002743 ASSERT(framebuffer);
2744
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002745 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002746 {
Jamie Madill437fa652016-05-03 15:13:24 -04002747 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002748 }
Jamie Madill437fa652016-05-03 15:13:24 -04002749
2750 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002751}
2752
2753void Context::invalidateSubFramebuffer(GLenum target,
2754 GLsizei numAttachments,
2755 const GLenum *attachments,
2756 GLint x,
2757 GLint y,
2758 GLsizei width,
2759 GLsizei height)
2760{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002761 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002762 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002763
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002764 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002765 ASSERT(framebuffer);
2766
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002767 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002768 {
Jamie Madill437fa652016-05-03 15:13:24 -04002769 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002770 }
Jamie Madill437fa652016-05-03 15:13:24 -04002771
2772 Rectangle area(x, y, width, height);
2773 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002774}
2775
Jamie Madill73a84962016-02-12 09:27:23 -05002776void Context::texImage2D(GLenum target,
2777 GLint level,
2778 GLint internalformat,
2779 GLsizei width,
2780 GLsizei height,
2781 GLint border,
2782 GLenum format,
2783 GLenum type,
2784 const GLvoid *pixels)
2785{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002786 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002787
2788 Extents size(width, height, 1);
2789 Texture *texture =
2790 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002791 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002792 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002793}
2794
2795void Context::texImage3D(GLenum target,
2796 GLint level,
2797 GLint internalformat,
2798 GLsizei width,
2799 GLsizei height,
2800 GLsizei depth,
2801 GLint border,
2802 GLenum format,
2803 GLenum type,
2804 const GLvoid *pixels)
2805{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002806 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002807
2808 Extents size(width, height, depth);
2809 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002810 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002811 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002812}
2813
2814void Context::texSubImage2D(GLenum target,
2815 GLint level,
2816 GLint xoffset,
2817 GLint yoffset,
2818 GLsizei width,
2819 GLsizei height,
2820 GLenum format,
2821 GLenum type,
2822 const GLvoid *pixels)
2823{
2824 // Zero sized uploads are valid but no-ops
2825 if (width == 0 || height == 0)
2826 {
2827 return;
2828 }
2829
Jamie Madillad9f24e2016-02-12 09:27:24 -05002830 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002831
2832 Box area(xoffset, yoffset, 0, width, height, 1);
2833 Texture *texture =
2834 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002835 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002836 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002837}
2838
2839void Context::texSubImage3D(GLenum target,
2840 GLint level,
2841 GLint xoffset,
2842 GLint yoffset,
2843 GLint zoffset,
2844 GLsizei width,
2845 GLsizei height,
2846 GLsizei depth,
2847 GLenum format,
2848 GLenum type,
2849 const GLvoid *pixels)
2850{
2851 // Zero sized uploads are valid but no-ops
2852 if (width == 0 || height == 0 || depth == 0)
2853 {
2854 return;
2855 }
2856
Jamie Madillad9f24e2016-02-12 09:27:24 -05002857 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002858
2859 Box area(xoffset, yoffset, zoffset, width, height, depth);
2860 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002861 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002862 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002863}
2864
2865void Context::compressedTexImage2D(GLenum target,
2866 GLint level,
2867 GLenum internalformat,
2868 GLsizei width,
2869 GLsizei height,
2870 GLint border,
2871 GLsizei imageSize,
2872 const GLvoid *data)
2873{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002874 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002875
2876 Extents size(width, height, 1);
2877 Texture *texture =
2878 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002879 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2880 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002881 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002882}
2883
2884void Context::compressedTexImage3D(GLenum target,
2885 GLint level,
2886 GLenum internalformat,
2887 GLsizei width,
2888 GLsizei height,
2889 GLsizei depth,
2890 GLint border,
2891 GLsizei imageSize,
2892 const GLvoid *data)
2893{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002894 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002895
2896 Extents size(width, height, depth);
2897 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002898 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2899 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002900 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002901}
2902
2903void Context::compressedTexSubImage2D(GLenum target,
2904 GLint level,
2905 GLint xoffset,
2906 GLint yoffset,
2907 GLsizei width,
2908 GLsizei height,
2909 GLenum format,
2910 GLsizei imageSize,
2911 const GLvoid *data)
2912{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002913 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002914
2915 Box area(xoffset, yoffset, 0, width, height, 1);
2916 Texture *texture =
2917 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002918 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2919 format, imageSize,
2920 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002921}
2922
2923void Context::compressedTexSubImage3D(GLenum target,
2924 GLint level,
2925 GLint xoffset,
2926 GLint yoffset,
2927 GLint zoffset,
2928 GLsizei width,
2929 GLsizei height,
2930 GLsizei depth,
2931 GLenum format,
2932 GLsizei imageSize,
2933 const GLvoid *data)
2934{
2935 // Zero sized uploads are valid but no-ops
2936 if (width == 0 || height == 0)
2937 {
2938 return;
2939 }
2940
Jamie Madillad9f24e2016-02-12 09:27:24 -05002941 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002942
2943 Box area(xoffset, yoffset, zoffset, width, height, depth);
2944 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002945 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2946 format, imageSize,
2947 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002948}
2949
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002950void Context::generateMipmap(GLenum target)
2951{
2952 Texture *texture = getTargetTexture(target);
2953 handleError(texture->generateMipmap());
2954}
2955
Geoff Langc287ea62016-09-16 14:46:51 -04002956GLboolean Context::enableExtension(const char *name)
2957{
2958 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2959 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2960 const auto &extension = extensionInfos.at(name);
2961 ASSERT(extension.Enableable);
2962
2963 if (mExtensions.*(extension.ExtensionsMember))
2964 {
2965 // Extension already enabled
2966 return GL_TRUE;
2967 }
2968
2969 const auto &nativeExtensions = mImplementation->getNativeExtensions();
2970 if (!(nativeExtensions.*(extension.ExtensionsMember)))
2971 {
2972 // Underlying implementation does not support this valid extension
2973 return GL_FALSE;
2974 }
2975
2976 mExtensions.*(extension.ExtensionsMember) = true;
2977 updateCaps();
2978 initExtensionStrings();
2979 return GL_TRUE;
2980}
2981
Geoff Lang97073d12016-04-20 10:42:34 -07002982void Context::copyTextureCHROMIUM(GLuint sourceId,
2983 GLuint destId,
2984 GLint internalFormat,
2985 GLenum destType,
2986 GLboolean unpackFlipY,
2987 GLboolean unpackPremultiplyAlpha,
2988 GLboolean unpackUnmultiplyAlpha)
2989{
2990 syncStateForTexImage();
2991
2992 gl::Texture *sourceTexture = getTexture(sourceId);
2993 gl::Texture *destTexture = getTexture(destId);
2994 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
2995 unpackPremultiplyAlpha == GL_TRUE,
2996 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
2997}
2998
2999void Context::copySubTextureCHROMIUM(GLuint sourceId,
3000 GLuint destId,
3001 GLint xoffset,
3002 GLint yoffset,
3003 GLint x,
3004 GLint y,
3005 GLsizei width,
3006 GLsizei height,
3007 GLboolean unpackFlipY,
3008 GLboolean unpackPremultiplyAlpha,
3009 GLboolean unpackUnmultiplyAlpha)
3010{
3011 // Zero sized copies are valid but no-ops
3012 if (width == 0 || height == 0)
3013 {
3014 return;
3015 }
3016
3017 syncStateForTexImage();
3018
3019 gl::Texture *sourceTexture = getTexture(sourceId);
3020 gl::Texture *destTexture = getTexture(destId);
3021 Offset offset(xoffset, yoffset, 0);
3022 Rectangle area(x, y, width, height);
3023 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3024 unpackPremultiplyAlpha == GL_TRUE,
3025 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3026}
3027
Geoff Lang47110bf2016-04-20 11:13:22 -07003028void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3029{
3030 syncStateForTexImage();
3031
3032 gl::Texture *sourceTexture = getTexture(sourceId);
3033 gl::Texture *destTexture = getTexture(destId);
3034 handleError(destTexture->copyCompressedTexture(sourceTexture));
3035}
3036
Geoff Lang496c02d2016-10-20 11:38:11 -07003037void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003038{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003039 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003040 ASSERT(buffer);
3041
Geoff Lang496c02d2016-10-20 11:38:11 -07003042 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003043}
3044
3045GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3046{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003047 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003048 ASSERT(buffer);
3049
3050 Error error = buffer->map(access);
3051 if (error.isError())
3052 {
Jamie Madill437fa652016-05-03 15:13:24 -04003053 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003054 return nullptr;
3055 }
3056
3057 return buffer->getMapPointer();
3058}
3059
3060GLboolean Context::unmapBuffer(GLenum target)
3061{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003062 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003063 ASSERT(buffer);
3064
3065 GLboolean result;
3066 Error error = buffer->unmap(&result);
3067 if (error.isError())
3068 {
Jamie Madill437fa652016-05-03 15:13:24 -04003069 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003070 return GL_FALSE;
3071 }
3072
3073 return result;
3074}
3075
3076GLvoid *Context::mapBufferRange(GLenum target,
3077 GLintptr offset,
3078 GLsizeiptr length,
3079 GLbitfield access)
3080{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003081 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003082 ASSERT(buffer);
3083
3084 Error error = buffer->mapRange(offset, length, access);
3085 if (error.isError())
3086 {
Jamie Madill437fa652016-05-03 15:13:24 -04003087 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003088 return nullptr;
3089 }
3090
3091 return buffer->getMapPointer();
3092}
3093
3094void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3095{
3096 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3097}
3098
Jamie Madillad9f24e2016-02-12 09:27:24 -05003099void Context::syncStateForReadPixels()
3100{
3101 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3102}
3103
3104void Context::syncStateForTexImage()
3105{
3106 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3107}
3108
3109void Context::syncStateForClear()
3110{
3111 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3112}
3113
3114void Context::syncStateForBlit()
3115{
3116 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3117}
3118
Jamie Madillc20ab272016-06-09 07:20:46 -07003119void Context::activeTexture(GLenum texture)
3120{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003121 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003122}
3123
3124void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3125{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003126 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003127}
3128
3129void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3130{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003131 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003132}
3133
3134void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3135{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003136 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003137}
3138
3139void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3140{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003141 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003142}
3143
3144void Context::clearDepthf(GLclampf depth)
3145{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003146 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003147}
3148
3149void Context::clearStencil(GLint s)
3150{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003151 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003152}
3153
3154void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3155{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003156 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003157}
3158
3159void Context::cullFace(GLenum mode)
3160{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003161 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003162}
3163
3164void Context::depthFunc(GLenum func)
3165{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003166 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003167}
3168
3169void Context::depthMask(GLboolean flag)
3170{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003171 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003172}
3173
3174void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3175{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003176 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003177}
3178
3179void Context::disable(GLenum cap)
3180{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003181 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003182}
3183
3184void Context::disableVertexAttribArray(GLuint index)
3185{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003186 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003187}
3188
3189void Context::enable(GLenum cap)
3190{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003191 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003192}
3193
3194void Context::enableVertexAttribArray(GLuint index)
3195{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003196 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003197}
3198
3199void Context::frontFace(GLenum mode)
3200{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003201 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003202}
3203
3204void Context::hint(GLenum target, GLenum mode)
3205{
3206 switch (target)
3207 {
3208 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003209 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003210 break;
3211
3212 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003213 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003214 break;
3215
3216 default:
3217 UNREACHABLE();
3218 return;
3219 }
3220}
3221
3222void Context::lineWidth(GLfloat width)
3223{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003224 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003225}
3226
3227void Context::pixelStorei(GLenum pname, GLint param)
3228{
3229 switch (pname)
3230 {
3231 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003232 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003233 break;
3234
3235 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003236 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003237 break;
3238
3239 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003240 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003241 break;
3242
3243 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003244 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003245 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003246 break;
3247
3248 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003249 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003250 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003251 break;
3252
3253 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003254 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003255 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003256 break;
3257
3258 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003259 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003260 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003261 break;
3262
3263 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003264 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003265 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003266 break;
3267
3268 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003269 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003270 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003271 break;
3272
3273 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003274 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003275 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003276 break;
3277
3278 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003279 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003280 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003281 break;
3282
3283 default:
3284 UNREACHABLE();
3285 return;
3286 }
3287}
3288
3289void Context::polygonOffset(GLfloat factor, GLfloat units)
3290{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003291 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003292}
3293
3294void Context::sampleCoverage(GLclampf value, GLboolean invert)
3295{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003297}
3298
3299void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3300{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003301 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003302}
3303
3304void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3305{
3306 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3307 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003308 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003309 }
3310
3311 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3312 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003313 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003314 }
3315}
3316
3317void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3318{
3319 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3320 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003321 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003322 }
3323
3324 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3325 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003326 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003327 }
3328}
3329
3330void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3331{
3332 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3333 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335 }
3336
3337 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3338 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340 }
3341}
3342
3343void Context::vertexAttrib1f(GLuint index, GLfloat x)
3344{
3345 GLfloat vals[4] = {x, 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::vertexAttrib1fv(GLuint index, const GLfloat *values)
3350{
3351 GLfloat vals[4] = {values[0], 0, 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::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3356{
3357 GLfloat vals[4] = {x, y, 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::vertexAttrib2fv(GLuint index, const GLfloat *values)
3362{
3363 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365}
3366
3367void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3368{
3369 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003370 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003371}
3372
3373void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3374{
3375 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003376 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003377}
3378
3379void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3380{
3381 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003382 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003383}
3384
3385void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3386{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003387 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003388}
3389
3390void Context::vertexAttribPointer(GLuint index,
3391 GLint size,
3392 GLenum type,
3393 GLboolean normalized,
3394 GLsizei stride,
3395 const GLvoid *ptr)
3396{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003397 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3398 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003399}
3400
3401void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3402{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003403 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003404}
3405
3406void Context::vertexAttribIPointer(GLuint index,
3407 GLint size,
3408 GLenum type,
3409 GLsizei stride,
3410 const GLvoid *pointer)
3411{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003412 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3413 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003414}
3415
3416void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3417{
3418 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420}
3421
3422void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3423{
3424 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003425 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003426}
3427
3428void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3429{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003430 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003431}
3432
3433void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3434{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003435 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003436}
3437
3438void Context::debugMessageControl(GLenum source,
3439 GLenum type,
3440 GLenum severity,
3441 GLsizei count,
3442 const GLuint *ids,
3443 GLboolean enabled)
3444{
3445 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003446 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3447 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003448}
3449
3450void Context::debugMessageInsert(GLenum source,
3451 GLenum type,
3452 GLuint id,
3453 GLenum severity,
3454 GLsizei length,
3455 const GLchar *buf)
3456{
3457 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003458 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003459}
3460
3461void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3462{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003463 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003464}
3465
3466GLuint Context::getDebugMessageLog(GLuint count,
3467 GLsizei bufSize,
3468 GLenum *sources,
3469 GLenum *types,
3470 GLuint *ids,
3471 GLenum *severities,
3472 GLsizei *lengths,
3473 GLchar *messageLog)
3474{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003475 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3476 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003477}
3478
3479void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3480{
3481 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003482 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003483}
3484
3485void Context::popDebugGroup()
3486{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003487 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003488}
3489
Jamie Madill29639852016-09-02 15:00:09 -04003490void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3491{
3492 Buffer *buffer = mGLState.getTargetBuffer(target);
3493 ASSERT(buffer);
3494 handleError(buffer->bufferData(target, data, size, usage));
3495}
3496
3497void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3498{
3499 if (data == nullptr)
3500 {
3501 return;
3502 }
3503
3504 Buffer *buffer = mGLState.getTargetBuffer(target);
3505 ASSERT(buffer);
3506 handleError(buffer->bufferSubData(target, data, size, offset));
3507}
3508
Jamie Madillef300b12016-10-07 15:12:09 -04003509void Context::attachShader(GLuint program, GLuint shader)
3510{
3511 auto programObject = mResourceManager->getProgram(program);
3512 auto shaderObject = mResourceManager->getShader(shader);
3513 ASSERT(programObject && shaderObject);
3514 programObject->attachShader(shaderObject);
3515}
3516
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003517const Workarounds &Context::getWorkarounds() const
3518{
3519 return mWorkarounds;
3520}
3521
Jamie Madillc29968b2016-01-20 11:17:23 -05003522} // namespace gl