blob: 755f12b39d180cfa3a8bc1790916577e3a92c621 [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"
Jamie Madill437fa652016-05-03 15:13:24 -040038#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040039#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030040#include "libANGLE/queryconversions.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000041
Geoff Langf6db0982015-08-25 13:04:00 -040042namespace
43{
44
Ian Ewell3ffd78b2016-01-22 16:09:42 -050045template <typename T>
Sami Väisänend59ca052016-06-21 16:10:00 +030046std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
47 GLsizei numPaths,
48 const void *paths,
49 GLuint pathBase)
50{
51 std::vector<gl::Path *> ret;
52 ret.reserve(numPaths);
53
54 const auto *nameArray = static_cast<const T *>(paths);
55
56 for (GLsizei i = 0; i < numPaths; ++i)
57 {
58 const GLuint pathName = nameArray[i] + pathBase;
59
60 ret.push_back(resourceManager.getPath(pathName));
61 }
62
63 return ret;
64}
65
66std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
67 GLsizei numPaths,
68 GLenum pathNameType,
69 const void *paths,
70 GLuint pathBase)
71{
72 switch (pathNameType)
73 {
74 case GL_UNSIGNED_BYTE:
75 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
76
77 case GL_BYTE:
78 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_UNSIGNED_SHORT:
81 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_SHORT:
84 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_UNSIGNED_INT:
87 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_INT:
90 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
91 }
92
93 UNREACHABLE();
94 return std::vector<gl::Path *>();
95}
96
97template <typename T>
Ian Ewell3ffd78b2016-01-22 16:09:42 -050098gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
99{
100 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
101 ASSERT(queryObject != nullptr);
102
103 switch (pname)
104 {
105 case GL_QUERY_RESULT_EXT:
106 return queryObject->getResult(params);
107 case GL_QUERY_RESULT_AVAILABLE_EXT:
108 {
109 bool available;
110 gl::Error error = queryObject->isResultAvailable(&available);
111 if (!error.isError())
112 {
113 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
114 }
115 return error;
116 }
117 default:
118 UNREACHABLE();
119 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
120 }
121}
122
Geoff Langf6db0982015-08-25 13:04:00 -0400123void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
124{
Geoff Lang1a683462015-09-29 15:09:59 -0400125 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400126 {
127 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
128 tfBufferIndex++)
129 {
130 const OffsetBindingPointer<gl::Buffer> &buffer =
131 transformFeedback->getIndexedBuffer(tfBufferIndex);
132 if (buffer.get() != nullptr)
133 {
134 buffer->onTransformFeedback();
135 }
136 }
137 }
138}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500139
140// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300141EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500142{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400143 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144}
145
Martin Radev1be913c2016-07-11 17:59:16 +0300146EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
147{
148 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
149}
150
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151GLenum GetResetStrategy(const egl::AttributeMap &attribs)
152{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400153 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
154 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500155 switch (attrib)
156 {
157 case EGL_NO_RESET_NOTIFICATION:
158 return GL_NO_RESET_NOTIFICATION_EXT;
159 case EGL_LOSE_CONTEXT_ON_RESET:
160 return GL_LOSE_CONTEXT_ON_RESET_EXT;
161 default:
162 UNREACHABLE();
163 return GL_NONE;
164 }
165}
166
167bool GetRobustAccess(const egl::AttributeMap &attribs)
168{
169 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
170}
171
172bool GetDebug(const egl::AttributeMap &attribs)
173{
174 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
175}
176
177bool GetNoError(const egl::AttributeMap &attribs)
178{
179 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
180}
181
Geoff Langc287ea62016-09-16 14:46:51 -0400182bool GetWebGLContext(const egl::AttributeMap &attribs)
183{
184 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
185}
186
Geoff Langf41a7152016-09-19 15:11:17 -0400187bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
190}
191
Martin Radev9d901792016-07-15 15:58:58 +0300192std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
193{
194 std::string labelName;
195 if (label != nullptr)
196 {
197 size_t labelLength = length < 0 ? strlen(label) : length;
198 labelName = std::string(label, labelLength);
199 }
200 return labelName;
201}
202
203void GetObjectLabelBase(const std::string &objectLabel,
204 GLsizei bufSize,
205 GLsizei *length,
206 GLchar *label)
207{
208 size_t writeLength = objectLabel.length();
209 if (label != nullptr && bufSize > 0)
210 {
211 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
212 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
213 label[writeLength] = '\0';
214 }
215
216 if (length != nullptr)
217 {
218 *length = static_cast<GLsizei>(writeLength);
219 }
220}
221
Geoff Langf6db0982015-08-25 13:04:00 -0400222} // anonymous namespace
223
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000224namespace gl
225{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000226
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400227Context::Context(rx::EGLImplFactory *implFactory,
228 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400229 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500230 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300231
232 : ValidationContext(GetClientMajorVersion(attribs),
233 GetClientMinorVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700234 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500235 mCaps,
236 mTextureCaps,
237 mExtensions,
238 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500239 mLimitations,
240 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700241 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500242 mCompiler(nullptr),
Martin Radev1be913c2016-07-11 17:59:16 +0300243 mClientMajorVersion(GetClientMajorVersion(attribs)),
244 mClientMinorVersion(GetClientMinorVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400245 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500246 mClientType(EGL_OPENGL_ES_API),
247 mHasBeenCurrent(false),
248 mContextLost(false),
249 mResetStatus(GL_NO_ERROR),
250 mResetStrategy(GetResetStrategy(attribs)),
251 mRobustAccess(GetRobustAccess(attribs)),
252 mCurrentSurface(nullptr),
253 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000254{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500255 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000256
Geoff Langc287ea62016-09-16 14:46:51 -0400257 initCaps(GetWebGLContext(attribs));
Geoff Langc0b9ef42014-07-02 10:02:37 -0400258
Geoff Langf41a7152016-09-19 15:11:17 -0400259 mGLState.initialize(mCaps, mExtensions, mClientMajorVersion, GetDebug(attribs),
260 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100261
Shannon Woods53a94a82014-06-24 15:20:36 -0400262 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400263
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400264 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000265 {
266 mResourceManager = shareContext->mResourceManager;
267 mResourceManager->addRef();
268 }
269 else
270 {
Jamie Madill901b3792016-05-26 09:20:40 -0400271 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000272 }
273
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700274 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400275
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276 // [OpenGL ES 2.0.24] section 3.7 page 83:
277 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
278 // and cube map texture state vectors respectively associated with them.
279 // In order that access to these initial textures not be lost, they are treated as texture
280 // objects all of whose names are 0.
281
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400282 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500283 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500284
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400285 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500286 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400287
Martin Radev1be913c2016-07-11 17:59:16 +0300288 if (mClientMajorVersion >= 3)
Geoff Lang76b10c92014-09-05 16:28:14 -0400289 {
290 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400291 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500292 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400296 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000297
Ian Ewellbda75592016-04-18 17:25:54 -0400298 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
299 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400300 Texture *zeroTextureExternal =
301 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400302 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
303 }
304
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700305 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500306
Jamie Madill57a89722013-07-02 11:57:03 -0400307 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000308 bindArrayBuffer(0);
309 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400310
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000311 bindRenderbuffer(0);
312
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000313 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400314 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000315 {
316 bindIndexedUniformBuffer(0, i, 0, -1);
317 }
318
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000319 bindCopyReadBuffer(0);
320 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000321 bindPixelPackBuffer(0);
322 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000323
Martin Radev1be913c2016-07-11 17:59:16 +0300324 if (mClientMajorVersion >= 3)
Geoff Lang1a683462015-09-29 15:09:59 -0400325 {
326 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
327 // In the initial state, a default transform feedback object is bound and treated as
328 // a transform feedback object with a name of zero. That object is bound any time
329 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400330 bindTransformFeedback(0);
331 }
Geoff Langc8058452014-02-03 12:04:11 -0500332
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700333 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500334
335 // Initialize dirty bit masks
336 // TODO(jmadill): additional ES3 state
337 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
338 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
339 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
340 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
341 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
342 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400343 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500344 // No dirty objects.
345
346 // Readpixels uses the pack state and read FBO
347 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
348 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
349 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
350 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
351 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400352 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500353 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
354
355 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
356 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
357 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
358 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
359 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
360 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
361 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
362 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
363 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
364 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
365 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
366 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
367
368 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
369 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
370 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
371 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400372
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400373 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000374}
375
376Context::~Context()
377{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700378 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000379
Corentin Wallez37c39792015-08-20 14:19:46 -0400380 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000381 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400382 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400383 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400384 {
385 SafeDelete(framebuffer.second);
386 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000387 }
388
Corentin Wallez80b24112015-08-25 16:41:57 -0400389 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000390 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400391 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000392 }
393
Corentin Wallez80b24112015-08-25 16:41:57 -0400394 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400396 if (query.second != nullptr)
397 {
398 query.second->release();
399 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000400 }
401
Corentin Wallez80b24112015-08-25 16:41:57 -0400402 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400403 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400404 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400405 }
406
Corentin Wallez80b24112015-08-25 16:41:57 -0400407 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500408 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500409 if (transformFeedback.second != nullptr)
410 {
411 transformFeedback.second->release();
412 }
Geoff Langc8058452014-02-03 12:04:11 -0500413 }
414
Jamie Madilldedd7b92014-11-05 16:30:36 -0500415 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400416 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500417 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400418 }
419 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420
Corentin Wallez51706ea2015-08-07 14:39:22 -0400421 if (mCurrentSurface != nullptr)
422 {
423 releaseSurface();
424 }
425
Jamie Madill1e9ae072014-11-06 15:27:21 -0500426 if (mResourceManager)
427 {
428 mResourceManager->release();
429 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500430
431 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000432}
433
daniel@transgaming.comad629872012-11-28 19:32:06 +0000434void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435{
Jamie Madill77a72f62015-04-14 11:18:32 -0400436 ASSERT(surface != nullptr);
437
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438 if (!mHasBeenCurrent)
439 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000440 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400441 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000442
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700443 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
444 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000445
446 mHasBeenCurrent = true;
447 }
448
Jamie Madill1b94d432015-08-07 13:23:23 -0400449 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700450 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400451
Corentin Wallez51706ea2015-08-07 14:39:22 -0400452 if (mCurrentSurface)
453 {
454 releaseSurface();
455 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000456 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400457 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000458
Corentin Wallez37c39792015-08-20 14:19:46 -0400459 // Update default framebuffer, the binding of the previous default
460 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400461 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400462 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700463 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400464 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700465 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400466 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700467 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400468 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700469 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400470 }
471 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400472 }
Ian Ewell292f0052016-02-04 10:37:32 -0500473
474 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700475 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000476}
477
Jamie Madill77a72f62015-04-14 11:18:32 -0400478void Context::releaseSurface()
479{
Corentin Wallez37c39792015-08-20 14:19:46 -0400480 ASSERT(mCurrentSurface != nullptr);
481
482 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400483 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400484 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700485 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400486 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700487 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400488 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700489 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400490 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700491 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400492 }
493 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400494 }
495
Corentin Wallez51706ea2015-08-07 14:39:22 -0400496 mCurrentSurface->setIsCurrent(false);
497 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400498}
499
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000500GLuint Context::createBuffer()
501{
502 return mResourceManager->createBuffer();
503}
504
505GLuint Context::createProgram()
506{
Jamie Madill901b3792016-05-26 09:20:40 -0400507 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000508}
509
510GLuint Context::createShader(GLenum type)
511{
Jamie Madill901b3792016-05-26 09:20:40 -0400512 return mResourceManager->createShader(mImplementation.get(),
513 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000514}
515
516GLuint Context::createTexture()
517{
518 return mResourceManager->createTexture();
519}
520
521GLuint Context::createRenderbuffer()
522{
523 return mResourceManager->createRenderbuffer();
524}
525
Geoff Lang882033e2014-09-30 11:26:07 -0400526GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400527{
Jamie Madill901b3792016-05-26 09:20:40 -0400528 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400529
Cooper Partind8e62a32015-01-29 15:21:25 -0800530 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400531}
532
Sami Väisänene45e53b2016-05-25 10:36:04 +0300533GLuint Context::createPaths(GLsizei range)
534{
535 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
536 if (resultOrError.isError())
537 {
538 handleError(resultOrError.getError());
539 return 0;
540 }
541 return resultOrError.getResult();
542}
543
Jamie Madill57a89722013-07-02 11:57:03 -0400544GLuint Context::createVertexArray()
545{
Geoff Lang36167ab2015-12-07 10:27:14 -0500546 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
547 mVertexArrayMap[vertexArray] = nullptr;
548 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400549}
550
Jamie Madilldc356042013-07-19 16:36:57 -0400551GLuint Context::createSampler()
552{
553 return mResourceManager->createSampler();
554}
555
Geoff Langc8058452014-02-03 12:04:11 -0500556GLuint Context::createTransformFeedback()
557{
Geoff Lang36167ab2015-12-07 10:27:14 -0500558 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
559 mTransformFeedbackMap[transformFeedback] = nullptr;
560 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500561}
562
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000563// Returns an unused framebuffer name
564GLuint Context::createFramebuffer()
565{
566 GLuint handle = mFramebufferHandleAllocator.allocate();
567
568 mFramebufferMap[handle] = NULL;
569
570 return handle;
571}
572
Jamie Madill33dc8432013-07-26 11:55:05 -0400573GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000574{
Jamie Madill33dc8432013-07-26 11:55:05 -0400575 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000576
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400577 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000578
579 return handle;
580}
581
582// Returns an unused query name
583GLuint Context::createQuery()
584{
585 GLuint handle = mQueryHandleAllocator.allocate();
586
587 mQueryMap[handle] = NULL;
588
589 return handle;
590}
591
592void Context::deleteBuffer(GLuint buffer)
593{
594 if (mResourceManager->getBuffer(buffer))
595 {
596 detachBuffer(buffer);
597 }
Jamie Madill893ab082014-05-16 16:56:10 -0400598
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000599 mResourceManager->deleteBuffer(buffer);
600}
601
602void Context::deleteShader(GLuint shader)
603{
604 mResourceManager->deleteShader(shader);
605}
606
607void Context::deleteProgram(GLuint program)
608{
609 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000610}
611
612void Context::deleteTexture(GLuint texture)
613{
614 if (mResourceManager->getTexture(texture))
615 {
616 detachTexture(texture);
617 }
618
619 mResourceManager->deleteTexture(texture);
620}
621
622void Context::deleteRenderbuffer(GLuint renderbuffer)
623{
624 if (mResourceManager->getRenderbuffer(renderbuffer))
625 {
626 detachRenderbuffer(renderbuffer);
627 }
Jamie Madill893ab082014-05-16 16:56:10 -0400628
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629 mResourceManager->deleteRenderbuffer(renderbuffer);
630}
631
Jamie Madillcd055f82013-07-26 11:55:15 -0400632void Context::deleteFenceSync(GLsync fenceSync)
633{
634 // The spec specifies the underlying Fence object is not deleted until all current
635 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
636 // and since our API is currently designed for being called from a single thread, we can delete
637 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700638 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400639}
640
Sami Väisänene45e53b2016-05-25 10:36:04 +0300641void Context::deletePaths(GLuint first, GLsizei range)
642{
643 mResourceManager->deletePaths(first, range);
644}
645
646bool Context::hasPathData(GLuint path) const
647{
648 const auto *pathObj = mResourceManager->getPath(path);
649 if (pathObj == nullptr)
650 return false;
651
652 return pathObj->hasPathData();
653}
654
655bool Context::hasPath(GLuint path) const
656{
657 return mResourceManager->hasPath(path);
658}
659
660void Context::setPathCommands(GLuint path,
661 GLsizei numCommands,
662 const GLubyte *commands,
663 GLsizei numCoords,
664 GLenum coordType,
665 const void *coords)
666{
667 auto *pathObject = mResourceManager->getPath(path);
668
669 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
670}
671
672void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
673{
674 auto *pathObj = mResourceManager->getPath(path);
675
676 switch (pname)
677 {
678 case GL_PATH_STROKE_WIDTH_CHROMIUM:
679 pathObj->setStrokeWidth(value);
680 break;
681 case GL_PATH_END_CAPS_CHROMIUM:
682 pathObj->setEndCaps(static_cast<GLenum>(value));
683 break;
684 case GL_PATH_JOIN_STYLE_CHROMIUM:
685 pathObj->setJoinStyle(static_cast<GLenum>(value));
686 break;
687 case GL_PATH_MITER_LIMIT_CHROMIUM:
688 pathObj->setMiterLimit(value);
689 break;
690 case GL_PATH_STROKE_BOUND_CHROMIUM:
691 pathObj->setStrokeBound(value);
692 break;
693 default:
694 UNREACHABLE();
695 break;
696 }
697}
698
699void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
700{
701 const auto *pathObj = mResourceManager->getPath(path);
702
703 switch (pname)
704 {
705 case GL_PATH_STROKE_WIDTH_CHROMIUM:
706 *value = pathObj->getStrokeWidth();
707 break;
708 case GL_PATH_END_CAPS_CHROMIUM:
709 *value = static_cast<GLfloat>(pathObj->getEndCaps());
710 break;
711 case GL_PATH_JOIN_STYLE_CHROMIUM:
712 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
713 break;
714 case GL_PATH_MITER_LIMIT_CHROMIUM:
715 *value = pathObj->getMiterLimit();
716 break;
717 case GL_PATH_STROKE_BOUND_CHROMIUM:
718 *value = pathObj->getStrokeBound();
719 break;
720 default:
721 UNREACHABLE();
722 break;
723 }
724}
725
726void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
727{
728 mGLState.setPathStencilFunc(func, ref, mask);
729}
730
Jamie Madill57a89722013-07-02 11:57:03 -0400731void Context::deleteVertexArray(GLuint vertexArray)
732{
Geoff Lang36167ab2015-12-07 10:27:14 -0500733 auto iter = mVertexArrayMap.find(vertexArray);
734 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000735 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500736 VertexArray *vertexArrayObject = iter->second;
737 if (vertexArrayObject != nullptr)
738 {
739 detachVertexArray(vertexArray);
740 delete vertexArrayObject;
741 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000742
Geoff Lang36167ab2015-12-07 10:27:14 -0500743 mVertexArrayMap.erase(iter);
744 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400745 }
746}
747
Jamie Madilldc356042013-07-19 16:36:57 -0400748void Context::deleteSampler(GLuint sampler)
749{
750 if (mResourceManager->getSampler(sampler))
751 {
752 detachSampler(sampler);
753 }
754
755 mResourceManager->deleteSampler(sampler);
756}
757
Geoff Langc8058452014-02-03 12:04:11 -0500758void Context::deleteTransformFeedback(GLuint transformFeedback)
759{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500760 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500761 if (iter != mTransformFeedbackMap.end())
762 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500763 TransformFeedback *transformFeedbackObject = iter->second;
764 if (transformFeedbackObject != nullptr)
765 {
766 detachTransformFeedback(transformFeedback);
767 transformFeedbackObject->release();
768 }
769
Geoff Lang50b3fe82015-12-08 14:49:12 +0000770 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500771 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500772 }
773}
774
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000775void Context::deleteFramebuffer(GLuint framebuffer)
776{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500777 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000778
779 if (framebufferObject != mFramebufferMap.end())
780 {
781 detachFramebuffer(framebuffer);
782
783 mFramebufferHandleAllocator.release(framebufferObject->first);
784 delete framebufferObject->second;
785 mFramebufferMap.erase(framebufferObject);
786 }
787}
788
Jamie Madill33dc8432013-07-26 11:55:05 -0400789void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000790{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500791 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000792
Jamie Madill33dc8432013-07-26 11:55:05 -0400793 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400795 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400797 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798 }
799}
800
801void Context::deleteQuery(GLuint query)
802{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500803 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000804 if (queryObject != mQueryMap.end())
805 {
806 mQueryHandleAllocator.release(queryObject->first);
807 if (queryObject->second)
808 {
809 queryObject->second->release();
810 }
811 mQueryMap.erase(queryObject);
812 }
813}
814
Geoff Lang70d0f492015-12-10 17:45:46 -0500815Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816{
817 return mResourceManager->getBuffer(handle);
818}
819
Geoff Lang48dcae72014-02-05 16:28:24 -0500820Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821{
822 return mResourceManager->getShader(handle);
823}
824
Geoff Lang48dcae72014-02-05 16:28:24 -0500825Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000826{
827 return mResourceManager->getProgram(handle);
828}
829
Jamie Madill570f7c82014-07-03 10:38:54 -0400830Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000831{
832 return mResourceManager->getTexture(handle);
833}
834
Geoff Lang70d0f492015-12-10 17:45:46 -0500835Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000836{
837 return mResourceManager->getRenderbuffer(handle);
838}
839
Jamie Madillcd055f82013-07-26 11:55:15 -0400840FenceSync *Context::getFenceSync(GLsync handle) const
841{
Minmin Gong794e0002015-04-07 18:31:54 -0700842 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400843}
844
Jamie Madill57a89722013-07-02 11:57:03 -0400845VertexArray *Context::getVertexArray(GLuint handle) const
846{
847 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500848 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400849}
850
Jamie Madilldc356042013-07-19 16:36:57 -0400851Sampler *Context::getSampler(GLuint handle) const
852{
853 return mResourceManager->getSampler(handle);
854}
855
Geoff Langc8058452014-02-03 12:04:11 -0500856TransformFeedback *Context::getTransformFeedback(GLuint handle) const
857{
Geoff Lang36167ab2015-12-07 10:27:14 -0500858 auto iter = mTransformFeedbackMap.find(handle);
859 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500860}
861
Geoff Lang70d0f492015-12-10 17:45:46 -0500862LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
863{
864 switch (identifier)
865 {
866 case GL_BUFFER:
867 return getBuffer(name);
868 case GL_SHADER:
869 return getShader(name);
870 case GL_PROGRAM:
871 return getProgram(name);
872 case GL_VERTEX_ARRAY:
873 return getVertexArray(name);
874 case GL_QUERY:
875 return getQuery(name);
876 case GL_TRANSFORM_FEEDBACK:
877 return getTransformFeedback(name);
878 case GL_SAMPLER:
879 return getSampler(name);
880 case GL_TEXTURE:
881 return getTexture(name);
882 case GL_RENDERBUFFER:
883 return getRenderbuffer(name);
884 case GL_FRAMEBUFFER:
885 return getFramebuffer(name);
886 default:
887 UNREACHABLE();
888 return nullptr;
889 }
890}
891
892LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
893{
894 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
895}
896
Martin Radev9d901792016-07-15 15:58:58 +0300897void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
898{
899 LabeledObject *object = getLabeledObject(identifier, name);
900 ASSERT(object != nullptr);
901
902 std::string labelName = GetObjectLabelFromPointer(length, label);
903 object->setLabel(labelName);
904}
905
906void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
907{
908 LabeledObject *object = getLabeledObjectFromPtr(ptr);
909 ASSERT(object != nullptr);
910
911 std::string labelName = GetObjectLabelFromPointer(length, label);
912 object->setLabel(labelName);
913}
914
915void Context::getObjectLabel(GLenum identifier,
916 GLuint name,
917 GLsizei bufSize,
918 GLsizei *length,
919 GLchar *label) const
920{
921 LabeledObject *object = getLabeledObject(identifier, name);
922 ASSERT(object != nullptr);
923
924 const std::string &objectLabel = object->getLabel();
925 GetObjectLabelBase(objectLabel, bufSize, length, label);
926}
927
928void Context::getObjectPtrLabel(const void *ptr,
929 GLsizei bufSize,
930 GLsizei *length,
931 GLchar *label) const
932{
933 LabeledObject *object = getLabeledObjectFromPtr(ptr);
934 ASSERT(object != nullptr);
935
936 const std::string &objectLabel = object->getLabel();
937 GetObjectLabelBase(objectLabel, bufSize, length, label);
938}
939
Jamie Madilldc356042013-07-19 16:36:57 -0400940bool Context::isSampler(GLuint samplerName) const
941{
942 return mResourceManager->isSampler(samplerName);
943}
944
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500945void Context::bindArrayBuffer(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.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000949}
950
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500951void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952{
Jamie Madill901b3792016-05-26 09:20:40 -0400953 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700954 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955}
956
Jamie Madilldedd7b92014-11-05 16:30:36 -0500957void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500959 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000960
Jamie Madilldedd7b92014-11-05 16:30:36 -0500961 if (handle == 0)
962 {
963 texture = mZeroTextures[target].get();
964 }
965 else
966 {
Jamie Madill901b3792016-05-26 09:20:40 -0400967 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500968 }
969
970 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700971 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000972}
973
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500974void Context::bindReadFramebuffer(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.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978}
979
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500980void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500982 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700983 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984}
985
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500986void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987{
Jamie Madill901b3792016-05-26 09:20:40 -0400988 Renderbuffer *renderbuffer =
989 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700990 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000991}
992
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500993void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400994{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500995 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700996 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400997}
998
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500999void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001000{
Geoff Lang76b10c92014-09-05 16:28:14 -04001001 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001002 Sampler *sampler =
1003 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001004 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001005}
1006
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001007void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001008{
Jamie Madill901b3792016-05-26 09:20:40 -04001009 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001010 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001011}
1012
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001013void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1014 GLuint index,
1015 GLintptr offset,
1016 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +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.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001020}
1021
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001022void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001023{
Jamie Madill901b3792016-05-26 09:20:40 -04001024 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001025 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001026}
1027
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001028void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1029 GLuint index,
1030 GLintptr offset,
1031 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +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.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindCopyReadBuffer(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.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001041}
1042
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001043void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +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.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001047}
1048
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001049void Context::bindPixelPackBuffer(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.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001053}
1054
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001055void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001056{
Jamie Madill901b3792016-05-26 09:20:40 -04001057 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001058 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001059}
1060
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001061void Context::useProgram(GLuint program)
1062{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001067{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001068 TransformFeedback *transformFeedback =
1069 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001070 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001071}
1072
Geoff Lang5aad9672014-09-08 11:10:42 -04001073Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001074{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001075 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001076 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077
Geoff Lang5aad9672014-09-08 11:10:42 -04001078 // begin query
1079 Error error = queryObject->begin();
1080 if (error.isError())
1081 {
1082 return error;
1083 }
1084
1085 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001086 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001087
Geoff Lang5aad9672014-09-08 11:10:42 -04001088 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001089}
1090
Geoff Lang5aad9672014-09-08 11:10:42 -04001091Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001092{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001093 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001094 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095
Geoff Lang5aad9672014-09-08 11:10:42 -04001096 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001097
Geoff Lang5aad9672014-09-08 11:10:42 -04001098 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001099 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001100
1101 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001102}
1103
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001104Error Context::queryCounter(GLuint id, GLenum target)
1105{
1106 ASSERT(target == GL_TIMESTAMP_EXT);
1107
1108 Query *queryObject = getQuery(id, true, target);
1109 ASSERT(queryObject);
1110
1111 return queryObject->queryCounter();
1112}
1113
1114void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1115{
1116 switch (pname)
1117 {
1118 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001119 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001120 break;
1121 case GL_QUERY_COUNTER_BITS_EXT:
1122 switch (target)
1123 {
1124 case GL_TIME_ELAPSED_EXT:
1125 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1126 break;
1127 case GL_TIMESTAMP_EXT:
1128 params[0] = getExtensions().queryCounterBitsTimestamp;
1129 break;
1130 default:
1131 UNREACHABLE();
1132 params[0] = 0;
1133 break;
1134 }
1135 break;
1136 default:
1137 UNREACHABLE();
1138 return;
1139 }
1140}
1141
1142Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
1143{
1144 return GetQueryObjectParameter(this, id, pname, params);
1145}
1146
1147Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1148{
1149 return GetQueryObjectParameter(this, id, pname, params);
1150}
1151
1152Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
1153{
1154 return GetQueryObjectParameter(this, id, pname, params);
1155}
1156
1157Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
1158{
1159 return GetQueryObjectParameter(this, id, pname, params);
1160}
1161
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001162Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001163{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001164 auto framebufferIt = mFramebufferMap.find(handle);
1165 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001166}
1167
Jamie Madill33dc8432013-07-26 11:55:05 -04001168FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001169{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001170 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171
Jamie Madill33dc8432013-07-26 11:55:05 -04001172 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173 {
1174 return NULL;
1175 }
1176 else
1177 {
1178 return fence->second;
1179 }
1180}
1181
1182Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1183{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001184 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185
1186 if (query == mQueryMap.end())
1187 {
1188 return NULL;
1189 }
1190 else
1191 {
1192 if (!query->second && create)
1193 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001194 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001195 query->second->addRef();
1196 }
1197 return query->second;
1198 }
1199}
1200
Geoff Lang70d0f492015-12-10 17:45:46 -05001201Query *Context::getQuery(GLuint handle) const
1202{
1203 auto iter = mQueryMap.find(handle);
1204 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1205}
1206
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001207Texture *Context::getTargetTexture(GLenum target) const
1208{
Ian Ewellbda75592016-04-18 17:25:54 -04001209 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001210 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001211}
1212
Geoff Lang76b10c92014-09-05 16:28:14 -04001213Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001214{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001215 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216}
1217
Geoff Lang492a7e42014-11-05 13:27:06 -05001218Compiler *Context::getCompiler() const
1219{
1220 return mCompiler;
1221}
1222
Jamie Madill893ab082014-05-16 16:56:10 -04001223void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001224{
1225 switch (pname)
1226 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001227 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001228 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001229 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001230 mGLState.getBooleanv(pname, params);
1231 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233}
1234
Jamie Madill893ab082014-05-16 16:56:10 -04001235void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236{
Shannon Woods53a94a82014-06-24 15:20:36 -04001237 // Queries about context capabilities and maximums are answered by Context.
1238 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001239 switch (pname)
1240 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001242 params[0] = mCaps.minAliasedLineWidth;
1243 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244 break;
1245 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001246 params[0] = mCaps.minAliasedPointSize;
1247 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001248 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001249 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001250 ASSERT(mExtensions.textureFilterAnisotropic);
1251 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001252 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001253 case GL_MAX_TEXTURE_LOD_BIAS:
1254 *params = mCaps.maxLODBias;
1255 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001256
1257 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1258 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1259 {
1260 ASSERT(mExtensions.pathRendering);
1261 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1262 memcpy(params, m, 16 * sizeof(GLfloat));
1263 }
1264 break;
1265
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001267 mGLState.getFloatv(pname, params);
1268 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001269 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270}
1271
Jamie Madill893ab082014-05-16 16:56:10 -04001272void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273{
Shannon Woods53a94a82014-06-24 15:20:36 -04001274 // Queries about context capabilities and maximums are answered by Context.
1275 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001276
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277 switch (pname)
1278 {
Geoff Lang301d1612014-07-09 10:34:37 -04001279 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1280 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1281 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001282 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1283 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1284 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001285 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1286 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1287 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001288 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001289 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1290 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1291 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001292 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001293 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001294 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1295 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1296 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1297 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001298 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1299 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001300 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1301 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001302 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001303 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1304 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1305 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1306 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001307 case GL_MAJOR_VERSION:
1308 *params = mClientMajorVersion;
1309 break;
1310 case GL_MINOR_VERSION:
1311 *params = mClientMinorVersion;
1312 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001313 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1314 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001315 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1316 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1317 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001318 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1319 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1320 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001321 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322 case GL_MAX_VIEWPORT_DIMS:
1323 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001324 params[0] = mCaps.maxViewportWidth;
1325 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 }
1327 break;
1328 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001329 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001331 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1332 *params = mResetStrategy;
1333 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001334 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001335 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001336 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001337 case GL_SHADER_BINARY_FORMATS:
1338 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1339 break;
1340 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001341 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001342 break;
1343 case GL_PROGRAM_BINARY_FORMATS:
1344 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001345 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001346 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001347 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001348 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001349
1350 // GL_KHR_debug
1351 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1352 *params = mExtensions.maxDebugMessageLength;
1353 break;
1354 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1355 *params = mExtensions.maxDebugLoggedMessages;
1356 break;
1357 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1358 *params = mExtensions.maxDebugGroupStackDepth;
1359 break;
1360 case GL_MAX_LABEL_LENGTH:
1361 *params = mExtensions.maxLabelLength;
1362 break;
1363
Ian Ewell53f59f42016-01-28 17:36:55 -05001364 // GL_EXT_disjoint_timer_query
1365 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001366 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001367 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001368 case GL_MAX_FRAMEBUFFER_WIDTH:
1369 *params = mCaps.maxFramebufferWidth;
1370 break;
1371 case GL_MAX_FRAMEBUFFER_HEIGHT:
1372 *params = mCaps.maxFramebufferHeight;
1373 break;
1374 case GL_MAX_FRAMEBUFFER_SAMPLES:
1375 *params = mCaps.maxFramebufferSamples;
1376 break;
1377 case GL_MAX_SAMPLE_MASK_WORDS:
1378 *params = mCaps.maxSampleMaskWords;
1379 break;
1380 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1381 *params = mCaps.maxColorTextureSamples;
1382 break;
1383 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1384 *params = mCaps.maxDepthTextureSamples;
1385 break;
1386 case GL_MAX_INTEGER_SAMPLES:
1387 *params = mCaps.maxIntegerSamples;
1388 break;
1389 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1390 *params = mCaps.maxVertexAttribRelativeOffset;
1391 break;
1392 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1393 *params = mCaps.maxVertexAttribBindings;
1394 break;
1395 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1396 *params = mCaps.maxVertexAttribStride;
1397 break;
1398 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1399 *params = mCaps.maxVertexAtomicCounterBuffers;
1400 break;
1401 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1402 *params = mCaps.maxVertexAtomicCounters;
1403 break;
1404 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1405 *params = mCaps.maxVertexImageUniforms;
1406 break;
1407 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1408 *params = mCaps.maxVertexShaderStorageBlocks;
1409 break;
1410 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1411 *params = mCaps.maxFragmentAtomicCounterBuffers;
1412 break;
1413 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1414 *params = mCaps.maxFragmentAtomicCounters;
1415 break;
1416 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1417 *params = mCaps.maxFragmentImageUniforms;
1418 break;
1419 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1420 *params = mCaps.maxFragmentShaderStorageBlocks;
1421 break;
1422 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1423 *params = mCaps.minProgramTextureGatherOffset;
1424 break;
1425 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1426 *params = mCaps.maxProgramTextureGatherOffset;
1427 break;
1428 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1429 *params = mCaps.maxComputeWorkGroupInvocations;
1430 break;
1431 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1432 *params = mCaps.maxComputeUniformBlocks;
1433 break;
1434 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1435 *params = mCaps.maxComputeTextureImageUnits;
1436 break;
1437 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1438 *params = mCaps.maxComputeSharedMemorySize;
1439 break;
1440 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1441 *params = mCaps.maxComputeUniformComponents;
1442 break;
1443 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1444 *params = mCaps.maxComputeAtomicCounterBuffers;
1445 break;
1446 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1447 *params = mCaps.maxComputeAtomicCounters;
1448 break;
1449 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1450 *params = mCaps.maxComputeImageUniforms;
1451 break;
1452 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1453 *params = mCaps.maxCombinedComputeUniformComponents;
1454 break;
1455 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1456 *params = mCaps.maxComputeShaderStorageBlocks;
1457 break;
1458 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1459 *params = mCaps.maxCombinedShaderOutputResources;
1460 break;
1461 case GL_MAX_UNIFORM_LOCATIONS:
1462 *params = mCaps.maxUniformLocations;
1463 break;
1464 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1465 *params = mCaps.maxAtomicCounterBufferBindings;
1466 break;
1467 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1468 *params = mCaps.maxAtomicCounterBufferSize;
1469 break;
1470 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1471 *params = mCaps.maxCombinedAtomicCounterBuffers;
1472 break;
1473 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1474 *params = mCaps.maxCombinedAtomicCounters;
1475 break;
1476 case GL_MAX_IMAGE_UNITS:
1477 *params = mCaps.maxImageUnits;
1478 break;
1479 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1480 *params = mCaps.maxCombinedImageUniforms;
1481 break;
1482 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1483 *params = mCaps.maxShaderStorageBufferBindings;
1484 break;
1485 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1486 *params = mCaps.maxCombinedShaderStorageBlocks;
1487 break;
1488 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1489 *params = mCaps.shaderStorageBufferOffsetAlignment;
1490 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001491 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001492 mGLState.getIntegerv(mState, pname, params);
1493 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001494 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001495}
1496
Jamie Madill893ab082014-05-16 16:56:10 -04001497void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001498{
Shannon Woods53a94a82014-06-24 15:20:36 -04001499 // Queries about context capabilities and maximums are answered by Context.
1500 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001501 switch (pname)
1502 {
1503 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001504 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001505 break;
1506 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001507 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001508 break;
1509 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001510 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001511 break;
1512 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001513 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001514 break;
1515 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001516 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001517 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001518
1519 // GL_EXT_disjoint_timer_query
1520 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001521 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001522 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001523
1524 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1525 *params = mCaps.maxShaderStorageBlockSize;
1526 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001527 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001528 UNREACHABLE();
1529 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001530 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001531}
1532
Geoff Lang70d0f492015-12-10 17:45:46 -05001533void Context::getPointerv(GLenum pname, void **params) const
1534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001535 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001536}
1537
Martin Radev66fb8202016-07-28 11:45:20 +03001538void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001539{
Shannon Woods53a94a82014-06-24 15:20:36 -04001540 // Queries about context capabilities and maximums are answered by Context.
1541 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001542
1543 GLenum nativeType;
1544 unsigned int numParams;
1545 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001546 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001547 ASSERT(queryStatus);
1548
1549 if (nativeType == GL_INT)
1550 {
1551 switch (target)
1552 {
1553 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1554 ASSERT(index < 3u);
1555 *data = mCaps.maxComputeWorkGroupCount[index];
1556 break;
1557 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1558 ASSERT(index < 3u);
1559 *data = mCaps.maxComputeWorkGroupSize[index];
1560 break;
1561 default:
1562 mGLState.getIntegeri_v(target, index, data);
1563 }
1564 }
1565 else
1566 {
1567 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1568 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001569}
1570
Martin Radev66fb8202016-07-28 11:45:20 +03001571void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001572{
Shannon Woods53a94a82014-06-24 15:20:36 -04001573 // Queries about context capabilities and maximums are answered by Context.
1574 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001575
1576 GLenum nativeType;
1577 unsigned int numParams;
1578 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001579 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001580 ASSERT(queryStatus);
1581
1582 if (nativeType == GL_INT_64_ANGLEX)
1583 {
1584 mGLState.getInteger64i_v(target, index, data);
1585 }
1586 else
1587 {
1588 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1589 }
1590}
1591
1592void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1593{
1594 // Queries about context capabilities and maximums are answered by Context.
1595 // Queries about current GL state values are answered by State.
1596
1597 GLenum nativeType;
1598 unsigned int numParams;
1599 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001600 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001601 ASSERT(queryStatus);
1602
1603 if (nativeType == GL_BOOL)
1604 {
1605 mGLState.getBooleani_v(target, index, data);
1606 }
1607 else
1608 {
1609 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1610 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001611}
1612
Geoff Langf6db0982015-08-25 13:04:00 -04001613Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001614{
Jamie Madill1b94d432015-08-07 13:23:23 -04001615 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001616 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001617 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001618
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001619 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001620}
1621
Geoff Langf6db0982015-08-25 13:04:00 -04001622Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1623{
1624 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001625 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001626 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001627
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001628 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001629}
1630
1631Error Context::drawElements(GLenum mode,
1632 GLsizei count,
1633 GLenum type,
1634 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001635 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001636{
Jamie Madill1b94d432015-08-07 13:23:23 -04001637 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001638 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001639}
1640
1641Error Context::drawElementsInstanced(GLenum mode,
1642 GLsizei count,
1643 GLenum type,
1644 const GLvoid *indices,
1645 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001646 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001647{
1648 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001649 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1650 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001651}
1652
1653Error Context::drawRangeElements(GLenum mode,
1654 GLuint start,
1655 GLuint end,
1656 GLsizei count,
1657 GLenum type,
1658 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001659 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001660{
1661 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001662 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001663}
1664
Geoff Lang129753a2015-01-09 16:52:09 -05001665Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001666{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001667 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001668}
1669
1670Error Context::finish()
1671{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001672 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001673}
1674
Austin Kinross6ee1e782015-05-29 17:05:37 -07001675void Context::insertEventMarker(GLsizei length, const char *marker)
1676{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001677 ASSERT(mImplementation);
1678 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001679}
1680
1681void Context::pushGroupMarker(GLsizei length, const char *marker)
1682{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001683 ASSERT(mImplementation);
1684 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001685}
1686
1687void Context::popGroupMarker()
1688{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001689 ASSERT(mImplementation);
1690 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001691}
1692
Geoff Langd8605522016-04-13 10:19:12 -04001693void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1694{
1695 Program *programObject = getProgram(program);
1696 ASSERT(programObject);
1697
1698 programObject->bindUniformLocation(location, name);
1699}
1700
Sami Väisänena797e062016-05-12 15:23:40 +03001701void Context::setCoverageModulation(GLenum components)
1702{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001703 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001704}
1705
Sami Väisänene45e53b2016-05-25 10:36:04 +03001706void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1707{
1708 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1709}
1710
1711void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1712{
1713 GLfloat I[16];
1714 angle::Matrix<GLfloat>::setToIdentity(I);
1715
1716 mGLState.loadPathRenderingMatrix(matrixMode, I);
1717}
1718
1719void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1720{
1721 const auto *pathObj = mResourceManager->getPath(path);
1722 if (!pathObj)
1723 return;
1724
1725 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1726 syncRendererState();
1727
1728 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1729}
1730
1731void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1732{
1733 const auto *pathObj = mResourceManager->getPath(path);
1734 if (!pathObj)
1735 return;
1736
1737 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1738 syncRendererState();
1739
1740 mImplementation->stencilStrokePath(pathObj, reference, mask);
1741}
1742
1743void Context::coverFillPath(GLuint path, GLenum coverMode)
1744{
1745 const auto *pathObj = mResourceManager->getPath(path);
1746 if (!pathObj)
1747 return;
1748
1749 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1750 syncRendererState();
1751
1752 mImplementation->coverFillPath(pathObj, coverMode);
1753}
1754
1755void Context::coverStrokePath(GLuint path, GLenum coverMode)
1756{
1757 const auto *pathObj = mResourceManager->getPath(path);
1758 if (!pathObj)
1759 return;
1760
1761 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1762 syncRendererState();
1763
1764 mImplementation->coverStrokePath(pathObj, coverMode);
1765}
1766
1767void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1768{
1769 const auto *pathObj = mResourceManager->getPath(path);
1770 if (!pathObj)
1771 return;
1772
1773 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1774 syncRendererState();
1775
1776 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1777}
1778
1779void Context::stencilThenCoverStrokePath(GLuint path,
1780 GLint reference,
1781 GLuint mask,
1782 GLenum coverMode)
1783{
1784 const auto *pathObj = mResourceManager->getPath(path);
1785 if (!pathObj)
1786 return;
1787
1788 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1789 syncRendererState();
1790
1791 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1792}
1793
Sami Väisänend59ca052016-06-21 16:10:00 +03001794void Context::coverFillPathInstanced(GLsizei numPaths,
1795 GLenum pathNameType,
1796 const void *paths,
1797 GLuint pathBase,
1798 GLenum coverMode,
1799 GLenum transformType,
1800 const GLfloat *transformValues)
1801{
1802 const auto &pathObjects =
1803 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1804
1805 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1806 syncRendererState();
1807
1808 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1809}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001810
Sami Väisänend59ca052016-06-21 16:10:00 +03001811void Context::coverStrokePathInstanced(GLsizei numPaths,
1812 GLenum pathNameType,
1813 const void *paths,
1814 GLuint pathBase,
1815 GLenum coverMode,
1816 GLenum transformType,
1817 const GLfloat *transformValues)
1818{
1819 const auto &pathObjects =
1820 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1821
1822 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1823 syncRendererState();
1824
1825 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1826 transformValues);
1827}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001828
Sami Väisänend59ca052016-06-21 16:10:00 +03001829void Context::stencilFillPathInstanced(GLsizei numPaths,
1830 GLenum pathNameType,
1831 const void *paths,
1832 GLuint pathBase,
1833 GLenum fillMode,
1834 GLuint mask,
1835 GLenum transformType,
1836 const GLfloat *transformValues)
1837{
1838 const auto &pathObjects =
1839 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1840
1841 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1842 syncRendererState();
1843
1844 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1845 transformValues);
1846}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001847
Sami Väisänend59ca052016-06-21 16:10:00 +03001848void Context::stencilStrokePathInstanced(GLsizei numPaths,
1849 GLenum pathNameType,
1850 const void *paths,
1851 GLuint pathBase,
1852 GLint reference,
1853 GLuint mask,
1854 GLenum transformType,
1855 const GLfloat *transformValues)
1856{
1857 const auto &pathObjects =
1858 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1859
1860 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1861 syncRendererState();
1862
1863 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1864 transformValues);
1865}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001866
Sami Väisänend59ca052016-06-21 16:10:00 +03001867void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1868 GLenum pathNameType,
1869 const void *paths,
1870 GLuint pathBase,
1871 GLenum fillMode,
1872 GLuint mask,
1873 GLenum coverMode,
1874 GLenum transformType,
1875 const GLfloat *transformValues)
1876{
1877 const auto &pathObjects =
1878 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1879
1880 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1881 syncRendererState();
1882
1883 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1884 transformType, transformValues);
1885}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001886
Sami Väisänend59ca052016-06-21 16:10:00 +03001887void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1888 GLenum pathNameType,
1889 const void *paths,
1890 GLuint pathBase,
1891 GLint reference,
1892 GLuint mask,
1893 GLenum coverMode,
1894 GLenum transformType,
1895 const GLfloat *transformValues)
1896{
1897 const auto &pathObjects =
1898 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1899
1900 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1901 syncRendererState();
1902
1903 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1904 transformType, transformValues);
1905}
1906
Sami Väisänen46eaa942016-06-29 10:26:37 +03001907void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1908{
1909 auto *programObject = getProgram(program);
1910
1911 programObject->bindFragmentInputLocation(location, name);
1912}
1913
1914void Context::programPathFragmentInputGen(GLuint program,
1915 GLint location,
1916 GLenum genMode,
1917 GLint components,
1918 const GLfloat *coeffs)
1919{
1920 auto *programObject = getProgram(program);
1921
1922 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1923}
1924
Jamie Madill437fa652016-05-03 15:13:24 -04001925void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001926{
Geoff Langda5777c2014-07-11 09:52:58 -04001927 if (error.isError())
1928 {
1929 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001930
1931 if (!error.getMessage().empty())
1932 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001933 auto *debug = &mGLState.getDebug();
1934 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1935 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001936 }
Geoff Langda5777c2014-07-11 09:52:58 -04001937 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001938}
1939
1940// Get one of the recorded errors and clear its flag, if any.
1941// [OpenGL ES 2.0.24] section 2.5 page 13.
1942GLenum Context::getError()
1943{
Geoff Langda5777c2014-07-11 09:52:58 -04001944 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001945 {
Geoff Langda5777c2014-07-11 09:52:58 -04001946 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001947 }
Geoff Langda5777c2014-07-11 09:52:58 -04001948 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001949 {
Geoff Langda5777c2014-07-11 09:52:58 -04001950 GLenum error = *mErrors.begin();
1951 mErrors.erase(mErrors.begin());
1952 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001953 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001954}
1955
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001956// NOTE: this function should not assume that this context is current!
1957void Context::markContextLost()
1958{
1959 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
1960 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
1961 mContextLost = true;
1962}
1963
1964bool Context::isContextLost()
1965{
1966 return mContextLost;
1967}
1968
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001969GLenum Context::getResetStatus()
1970{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001971 // Even if the application doesn't want to know about resets, we want to know
1972 // as it will allow us to skip all the calls.
1973 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001974 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001975 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001976 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001977 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001978 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001979
1980 // EXT_robustness, section 2.6: If the reset notification behavior is
1981 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1982 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1983 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001984 }
1985
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001986 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1987 // status should be returned at least once, and GL_NO_ERROR should be returned
1988 // once the device has finished resetting.
1989 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001990 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001991 ASSERT(mResetStatus == GL_NO_ERROR);
1992 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001993
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001994 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001995 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001996 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001997 }
1998 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001999 else if (mResetStatus != GL_NO_ERROR)
2000 {
2001 mResetStatus = mImplementation->getResetStatus();
2002 }
Jamie Madill893ab082014-05-16 16:56:10 -04002003
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002004 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002005}
2006
2007bool Context::isResetNotificationEnabled()
2008{
2009 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2010}
2011
Corentin Walleze3b10e82015-05-20 11:06:25 -04002012const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002013{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002014 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002015}
2016
2017EGLenum Context::getClientType() const
2018{
2019 return mClientType;
2020}
2021
2022EGLenum Context::getRenderBuffer() const
2023{
Corentin Wallez37c39792015-08-20 14:19:46 -04002024 auto framebufferIt = mFramebufferMap.find(0);
2025 if (framebufferIt != mFramebufferMap.end())
2026 {
2027 const Framebuffer *framebuffer = framebufferIt->second;
2028 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2029
2030 ASSERT(backAttachment != nullptr);
2031 return backAttachment->getSurface()->getRenderBuffer();
2032 }
2033 else
2034 {
2035 return EGL_NONE;
2036 }
Régis Fénéon83107972015-02-05 12:57:44 +01002037}
2038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002039VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002040{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002041 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002042 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2043 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002044 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002045 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2046
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002047 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002048 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002049
2050 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002051}
2052
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002053TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002054{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002055 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002056 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2057 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002058 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002059 transformFeedback =
2060 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002061 transformFeedback->addRef();
2062 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002063 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002064
2065 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002066}
2067
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002068Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2069{
2070 // Can be called from Bind without a prior call to Gen.
2071 auto framebufferIt = mFramebufferMap.find(framebuffer);
2072 bool neverCreated = framebufferIt == mFramebufferMap.end();
2073 if (neverCreated || framebufferIt->second == nullptr)
2074 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002075 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002076 if (neverCreated)
2077 {
2078 mFramebufferHandleAllocator.reserve(framebuffer);
2079 mFramebufferMap[framebuffer] = newFBO;
2080 return newFBO;
2081 }
2082
2083 framebufferIt->second = newFBO;
2084 }
2085
2086 return framebufferIt->second;
2087}
2088
Geoff Langf41a7152016-09-19 15:11:17 -04002089bool Context::isTextureGenerated(GLuint texture) const
2090{
2091 return mResourceManager->isTextureGenerated(texture);
2092}
2093
2094bool Context::isBufferGenerated(GLuint buffer) const
2095{
2096 return mResourceManager->isBufferGenerated(buffer);
2097}
2098
2099bool Context::isRenderbufferGenerated(GLuint renderbuffer) const
2100{
2101 return mResourceManager->isRenderbufferGenerated(renderbuffer);
2102}
2103
2104bool Context::isFramebufferGenerated(GLuint framebuffer) const
2105{
2106 ASSERT(mFramebufferMap.find(0) != mFramebufferMap.end());
2107 return mFramebufferMap.find(framebuffer) != mFramebufferMap.end();
2108}
2109
Geoff Lang36167ab2015-12-07 10:27:14 -05002110bool Context::isVertexArrayGenerated(GLuint vertexArray)
2111{
Geoff Langf41a7152016-09-19 15:11:17 -04002112 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002113 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2114}
2115
2116bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2117{
Geoff Langf41a7152016-09-19 15:11:17 -04002118 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002119 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2120}
2121
Shannon Woods53a94a82014-06-24 15:20:36 -04002122void Context::detachTexture(GLuint texture)
2123{
2124 // Simple pass-through to State's detachTexture method, as textures do not require
2125 // allocation map management either here or in the resource manager at detach time.
2126 // Zero textures are held by the Context, and we don't attempt to request them from
2127 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002128 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002129}
2130
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002131void Context::detachBuffer(GLuint buffer)
2132{
Yuly Novikov5807a532015-12-03 13:01:22 -05002133 // Simple pass-through to State's detachBuffer method, since
2134 // only buffer attachments to container objects that are bound to the current context
2135 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002136
Yuly Novikov5807a532015-12-03 13:01:22 -05002137 // [OpenGL ES 3.2] section 5.1.2 page 45:
2138 // Attachments to unbound container objects, such as
2139 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2140 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002141 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002142}
2143
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002144void Context::detachFramebuffer(GLuint framebuffer)
2145{
Shannon Woods53a94a82014-06-24 15:20:36 -04002146 // Framebuffer detachment is handled by Context, because 0 is a valid
2147 // Framebuffer object, and a pointer to it must be passed from Context
2148 // to State at binding time.
2149
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002150 // [OpenGL ES 2.0.24] section 4.4 page 107:
2151 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2152 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2153
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002154 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002155 {
2156 bindReadFramebuffer(0);
2157 }
2158
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002159 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002160 {
2161 bindDrawFramebuffer(0);
2162 }
2163}
2164
2165void Context::detachRenderbuffer(GLuint renderbuffer)
2166{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002167 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002168}
2169
Jamie Madill57a89722013-07-02 11:57:03 -04002170void Context::detachVertexArray(GLuint vertexArray)
2171{
Jamie Madill77a72f62015-04-14 11:18:32 -04002172 // Vertex array detachment is handled by Context, because 0 is a valid
2173 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002174 // binding time.
2175
Jamie Madill57a89722013-07-02 11:57:03 -04002176 // [OpenGL ES 3.0.2] section 2.10 page 43:
2177 // If a vertex array object that is currently bound is deleted, the binding
2178 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002179 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002180 {
2181 bindVertexArray(0);
2182 }
2183}
2184
Geoff Langc8058452014-02-03 12:04:11 -05002185void Context::detachTransformFeedback(GLuint transformFeedback)
2186{
Corentin Walleza2257da2016-04-19 16:43:12 -04002187 // Transform feedback detachment is handled by Context, because 0 is a valid
2188 // transform feedback, and a pointer to it must be passed from Context to State at
2189 // binding time.
2190
2191 // The OpenGL specification doesn't mention what should happen when the currently bound
2192 // transform feedback object is deleted. Since it is a container object, we treat it like
2193 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002194 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002195 {
2196 bindTransformFeedback(0);
2197 }
Geoff Langc8058452014-02-03 12:04:11 -05002198}
2199
Jamie Madilldc356042013-07-19 16:36:57 -04002200void Context::detachSampler(GLuint sampler)
2201{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002202 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002203}
2204
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002205void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2206{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002207 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002208}
2209
Jamie Madille29d1672013-07-19 16:36:57 -04002210void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2211{
Jamie Madill901b3792016-05-26 09:20:40 -04002212 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002213
2214 Sampler *samplerObject = getSampler(sampler);
2215 ASSERT(samplerObject);
2216
Geoff Lang69cce582015-09-17 13:20:36 -04002217 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002218 switch (pname)
2219 {
Geoff Lang69cce582015-09-17 13:20:36 -04002220 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
2221 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
2222 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
2223 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
2224 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
2225 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
2226 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
2227 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
2228 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
2229 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
2230 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002231 }
Geoff Lang69cce582015-09-17 13:20:36 -04002232 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002233}
2234
2235void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2236{
Jamie Madill901b3792016-05-26 09:20:40 -04002237 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002238
2239 Sampler *samplerObject = getSampler(sampler);
2240 ASSERT(samplerObject);
2241
Geoff Lang69cce582015-09-17 13:20:36 -04002242 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002243 switch (pname)
2244 {
Geoff Lang69cce582015-09-17 13:20:36 -04002245 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
2246 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
2247 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
2248 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
2249 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
2250 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
2251 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
2252 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
2253 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
2254 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
2255 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002256 }
Geoff Lang69cce582015-09-17 13:20:36 -04002257 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002258}
2259
Jamie Madill9675b802013-07-19 16:36:59 -04002260GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
2261{
Jamie Madill901b3792016-05-26 09:20:40 -04002262 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002263
2264 Sampler *samplerObject = getSampler(sampler);
2265 ASSERT(samplerObject);
2266
Geoff Lang69cce582015-09-17 13:20:36 -04002267 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002268 switch (pname)
2269 {
Geoff Lang69cce582015-09-17 13:20:36 -04002270 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
2271 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
2272 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
2273 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
2274 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
2275 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02002276 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
2277 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04002278 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
2279 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
2280 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002281 }
Geoff Lang69cce582015-09-17 13:20:36 -04002282 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002283}
2284
2285GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
2286{
Jamie Madill901b3792016-05-26 09:20:40 -04002287 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002288
2289 Sampler *samplerObject = getSampler(sampler);
2290 ASSERT(samplerObject);
2291
Geoff Lang69cce582015-09-17 13:20:36 -04002292 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002293 switch (pname)
2294 {
Geoff Lang69cce582015-09-17 13:20:36 -04002295 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
2296 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
2297 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
2298 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2299 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2300 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
2301 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2302 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2303 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2304 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2305 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002306 }
Geoff Lang69cce582015-09-17 13:20:36 -04002307 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002308}
2309
Olli Etuahof0fee072016-03-30 15:11:58 +03002310void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2311{
2312 gl::Program *programObject = getProgram(program);
2313 ASSERT(programObject != nullptr);
2314
2315 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2316 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2317}
2318
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002319void Context::initRendererString()
2320{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002321 std::ostringstream rendererString;
2322 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002323 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002324 rendererString << ")";
2325
Geoff Langcec35902014-04-16 10:52:36 -04002326 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002327}
2328
Geoff Langc287ea62016-09-16 14:46:51 -04002329const char *Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002330{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002331 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002332}
2333
Geoff Langcec35902014-04-16 10:52:36 -04002334void Context::initExtensionStrings()
2335{
Geoff Langc287ea62016-09-16 14:46:51 -04002336 for (const auto &extensionString : mExtensions.getStrings())
2337 {
2338 mExtensionStrings.push_back(MakeStaticString(extensionString));
2339 }
Geoff Langcec35902014-04-16 10:52:36 -04002340
Geoff Langc0b9ef42014-07-02 10:02:37 -04002341 std::ostringstream combinedStringStream;
Geoff Langc287ea62016-09-16 14:46:51 -04002342 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(),
2343 std::ostream_iterator<const char *>(combinedStringStream, " "));
2344 mExtensionString = MakeStaticString(combinedStringStream.str());
Geoff Langcec35902014-04-16 10:52:36 -04002345}
2346
Geoff Langc287ea62016-09-16 14:46:51 -04002347const char *Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002348{
2349 return mExtensionString;
2350}
2351
Geoff Langc287ea62016-09-16 14:46:51 -04002352const char *Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002353{
2354 return mExtensionStrings[idx];
2355}
2356
2357size_t Context::getExtensionStringCount() const
2358{
2359 return mExtensionStrings.size();
2360}
2361
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002362void Context::beginTransformFeedback(GLenum primitiveMode)
2363{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002364 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002365 ASSERT(transformFeedback != nullptr);
2366 ASSERT(!transformFeedback->isPaused());
2367
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002368 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002369}
2370
2371bool Context::hasActiveTransformFeedback(GLuint program) const
2372{
2373 for (auto pair : mTransformFeedbackMap)
2374 {
2375 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2376 {
2377 return true;
2378 }
2379 }
2380 return false;
2381}
2382
Geoff Langc287ea62016-09-16 14:46:51 -04002383void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002384{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002385 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002386
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002387 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002388
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002389 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002390
Martin Radev1be913c2016-07-11 17:59:16 +03002391 if (mClientMajorVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002392 {
2393 // Disable ES3+ extensions
2394 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002395 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002396 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002397 }
2398
Martin Radev1be913c2016-07-11 17:59:16 +03002399 if (mClientMajorVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002400 {
2401 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2402 //mExtensions.sRGB = false;
2403 }
2404
Jamie Madill00ed7a12016-05-19 13:13:38 -04002405 // Some extensions are always available because they are implemented in the GL layer.
2406 mExtensions.bindUniformLocation = true;
2407 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002408 mExtensions.bindGeneratesResource = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002409
2410 // Enable the no error extension if the context was created with the flag.
2411 mExtensions.noError = mSkipValidation;
2412
Geoff Lang70d0f492015-12-10 17:45:46 -05002413 // Explicitly enable GL_KHR_debug
2414 mExtensions.debug = true;
2415 mExtensions.maxDebugMessageLength = 1024;
2416 mExtensions.maxDebugLoggedMessages = 1024;
2417 mExtensions.maxDebugGroupStackDepth = 1024;
2418 mExtensions.maxLabelLength = 1024;
2419
Geoff Lang301d1612014-07-09 10:34:37 -04002420 // Apply implementation limits
2421 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002422 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2423 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2424
2425 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002426
Geoff Langc287ea62016-09-16 14:46:51 -04002427 // WebGL compatibility
2428 mExtensions.webglCompatibility = webGLContext;
2429 for (const auto &extensionInfo : GetExtensionInfoMap())
2430 {
2431 // If this context is for WebGL, disable all enableable extensions
2432 if (webGLContext && extensionInfo.second.Enableable)
2433 {
2434 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2435 }
2436 }
2437
2438 // Generate texture caps
2439 updateCaps();
2440}
2441
2442void Context::updateCaps()
2443{
Geoff Lang900013c2014-07-07 11:32:19 -04002444 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002445 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002446
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002447 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002448 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2449 {
2450 GLenum format = i->first;
2451 TextureCaps formatCaps = i->second;
2452
Geoff Lang5d601382014-07-22 15:14:06 -04002453 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002454
Geoff Lang0d8b7242015-09-09 14:56:53 -04002455 // Update the format caps based on the client version and extensions.
2456 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2457 // ES3.
2458 formatCaps.texturable =
Martin Radev1be913c2016-07-11 17:59:16 +03002459 formatCaps.texturable && formatInfo.textureSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002460 formatCaps.renderable =
Martin Radev1be913c2016-07-11 17:59:16 +03002461 formatCaps.renderable && formatInfo.renderSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002462 formatCaps.filterable =
Martin Radev1be913c2016-07-11 17:59:16 +03002463 formatCaps.filterable && formatInfo.filterSupport(mClientMajorVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002464
2465 // OpenGL ES does not support multisampling with integer formats
2466 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002467 {
Geoff Langd87878e2014-09-19 15:42:59 -04002468 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002469 }
Geoff Langd87878e2014-09-19 15:42:59 -04002470
2471 if (formatCaps.texturable && formatInfo.compressed)
2472 {
2473 mCaps.compressedTextureFormats.push_back(format);
2474 }
2475
2476 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002477 }
2478}
2479
Jamie Madill1b94d432015-08-07 13:23:23 -04002480void Context::syncRendererState()
2481{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002482 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2483 mImplementation->syncState(mGLState, dirtyBits);
2484 mGLState.clearDirtyBits();
2485 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002486}
2487
Jamie Madillad9f24e2016-02-12 09:27:24 -05002488void Context::syncRendererState(const State::DirtyBits &bitMask,
2489 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002490{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002491 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2492 mImplementation->syncState(mGLState, dirtyBits);
2493 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002494
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002495 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002496}
Jamie Madillc29968b2016-01-20 11:17:23 -05002497
2498void Context::blitFramebuffer(GLint srcX0,
2499 GLint srcY0,
2500 GLint srcX1,
2501 GLint srcY1,
2502 GLint dstX0,
2503 GLint dstY0,
2504 GLint dstX1,
2505 GLint dstY1,
2506 GLbitfield mask,
2507 GLenum filter)
2508{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002509 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002510 ASSERT(drawFramebuffer);
2511
2512 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2513 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2514
Jamie Madillad9f24e2016-02-12 09:27:24 -05002515 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002516
Jamie Madill8415b5f2016-04-26 13:41:39 -04002517 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002518}
Jamie Madillc29968b2016-01-20 11:17:23 -05002519
2520void Context::clear(GLbitfield mask)
2521{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002522 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002523 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002524}
2525
2526void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2527{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002528 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002529 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2530 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002531}
2532
2533void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2534{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002535 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002536 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2537 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002538}
2539
2540void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2541{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002542 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002543 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2544 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002545}
2546
2547void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002549 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002550 ASSERT(framebufferObject);
2551
2552 // If a buffer is not present, the clear has no effect
2553 if (framebufferObject->getDepthbuffer() == nullptr &&
2554 framebufferObject->getStencilbuffer() == nullptr)
2555 {
2556 return;
2557 }
2558
Jamie Madillad9f24e2016-02-12 09:27:24 -05002559 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002560 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2561 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002562}
2563
2564void Context::readPixels(GLint x,
2565 GLint y,
2566 GLsizei width,
2567 GLsizei height,
2568 GLenum format,
2569 GLenum type,
2570 GLvoid *pixels)
2571{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002572 if (width == 0 || height == 0)
2573 {
2574 return;
2575 }
2576
Jamie Madillad9f24e2016-02-12 09:27:24 -05002577 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002578
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002579 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002580 ASSERT(framebufferObject);
2581
2582 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002583 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002584}
2585
2586void Context::copyTexImage2D(GLenum target,
2587 GLint level,
2588 GLenum internalformat,
2589 GLint x,
2590 GLint y,
2591 GLsizei width,
2592 GLsizei height,
2593 GLint border)
2594{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002595 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002596 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002597
Jamie Madillc29968b2016-01-20 11:17:23 -05002598 Rectangle sourceArea(x, y, width, height);
2599
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002600 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002601 Texture *texture =
2602 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002603 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002604}
2605
2606void Context::copyTexSubImage2D(GLenum target,
2607 GLint level,
2608 GLint xoffset,
2609 GLint yoffset,
2610 GLint x,
2611 GLint y,
2612 GLsizei width,
2613 GLsizei height)
2614{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002615 if (width == 0 || height == 0)
2616 {
2617 return;
2618 }
2619
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002620 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002621 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002622
Jamie Madillc29968b2016-01-20 11:17:23 -05002623 Offset destOffset(xoffset, yoffset, 0);
2624 Rectangle sourceArea(x, y, width, height);
2625
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002626 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002627 Texture *texture =
2628 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002629 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002630}
2631
2632void Context::copyTexSubImage3D(GLenum target,
2633 GLint level,
2634 GLint xoffset,
2635 GLint yoffset,
2636 GLint zoffset,
2637 GLint x,
2638 GLint y,
2639 GLsizei width,
2640 GLsizei height)
2641{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002642 if (width == 0 || height == 0)
2643 {
2644 return;
2645 }
2646
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002647 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002648 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002649
Jamie Madillc29968b2016-01-20 11:17:23 -05002650 Offset destOffset(xoffset, yoffset, zoffset);
2651 Rectangle sourceArea(x, y, width, height);
2652
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002653 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002654 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002655 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002656}
2657
2658void Context::framebufferTexture2D(GLenum target,
2659 GLenum attachment,
2660 GLenum textarget,
2661 GLuint texture,
2662 GLint level)
2663{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002664 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002665 ASSERT(framebuffer);
2666
2667 if (texture != 0)
2668 {
2669 Texture *textureObj = getTexture(texture);
2670
2671 ImageIndex index = ImageIndex::MakeInvalid();
2672
2673 if (textarget == GL_TEXTURE_2D)
2674 {
2675 index = ImageIndex::Make2D(level);
2676 }
2677 else
2678 {
2679 ASSERT(IsCubeMapTextureTarget(textarget));
2680 index = ImageIndex::MakeCube(textarget, level);
2681 }
2682
2683 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2684 }
2685 else
2686 {
2687 framebuffer->resetAttachment(attachment);
2688 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002689
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002690 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002691}
2692
2693void Context::framebufferRenderbuffer(GLenum target,
2694 GLenum attachment,
2695 GLenum renderbuffertarget,
2696 GLuint renderbuffer)
2697{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002698 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002699 ASSERT(framebuffer);
2700
2701 if (renderbuffer != 0)
2702 {
2703 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2704 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2705 renderbufferObject);
2706 }
2707 else
2708 {
2709 framebuffer->resetAttachment(attachment);
2710 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002711
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002712 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002713}
2714
2715void Context::framebufferTextureLayer(GLenum target,
2716 GLenum attachment,
2717 GLuint texture,
2718 GLint level,
2719 GLint layer)
2720{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002721 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002722 ASSERT(framebuffer);
2723
2724 if (texture != 0)
2725 {
2726 Texture *textureObject = getTexture(texture);
2727
2728 ImageIndex index = ImageIndex::MakeInvalid();
2729
2730 if (textureObject->getTarget() == GL_TEXTURE_3D)
2731 {
2732 index = ImageIndex::Make3D(level, layer);
2733 }
2734 else
2735 {
2736 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2737 index = ImageIndex::Make2DArray(level, layer);
2738 }
2739
2740 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2741 }
2742 else
2743 {
2744 framebuffer->resetAttachment(attachment);
2745 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002746
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002747 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002748}
2749
2750void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2751{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002752 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002753 ASSERT(framebuffer);
2754 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002755 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002756}
2757
2758void Context::readBuffer(GLenum mode)
2759{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002760 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002761 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002762 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002763}
2764
2765void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2766{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002767 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002768 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002769
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002770 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002771 ASSERT(framebuffer);
2772
2773 // The specification isn't clear what should be done when the framebuffer isn't complete.
2774 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002775 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002776}
2777
2778void Context::invalidateFramebuffer(GLenum target,
2779 GLsizei numAttachments,
2780 const GLenum *attachments)
2781{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002782 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002783 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002784
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002785 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002786 ASSERT(framebuffer);
2787
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002788 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002789 {
Jamie Madill437fa652016-05-03 15:13:24 -04002790 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002791 }
Jamie Madill437fa652016-05-03 15:13:24 -04002792
2793 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002794}
2795
2796void Context::invalidateSubFramebuffer(GLenum target,
2797 GLsizei numAttachments,
2798 const GLenum *attachments,
2799 GLint x,
2800 GLint y,
2801 GLsizei width,
2802 GLsizei height)
2803{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002804 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002805 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002806
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002807 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002808 ASSERT(framebuffer);
2809
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002810 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002811 {
Jamie Madill437fa652016-05-03 15:13:24 -04002812 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002813 }
Jamie Madill437fa652016-05-03 15:13:24 -04002814
2815 Rectangle area(x, y, width, height);
2816 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002817}
2818
Jamie Madill73a84962016-02-12 09:27:23 -05002819void Context::texImage2D(GLenum target,
2820 GLint level,
2821 GLint internalformat,
2822 GLsizei width,
2823 GLsizei height,
2824 GLint border,
2825 GLenum format,
2826 GLenum type,
2827 const GLvoid *pixels)
2828{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002829 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002830
2831 Extents size(width, height, 1);
2832 Texture *texture =
2833 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002834 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002835 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002836}
2837
2838void Context::texImage3D(GLenum target,
2839 GLint level,
2840 GLint internalformat,
2841 GLsizei width,
2842 GLsizei height,
2843 GLsizei depth,
2844 GLint border,
2845 GLenum format,
2846 GLenum type,
2847 const GLvoid *pixels)
2848{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002849 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002850
2851 Extents size(width, height, depth);
2852 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002853 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002854 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002855}
2856
2857void Context::texSubImage2D(GLenum target,
2858 GLint level,
2859 GLint xoffset,
2860 GLint yoffset,
2861 GLsizei width,
2862 GLsizei height,
2863 GLenum format,
2864 GLenum type,
2865 const GLvoid *pixels)
2866{
2867 // Zero sized uploads are valid but no-ops
2868 if (width == 0 || height == 0)
2869 {
2870 return;
2871 }
2872
Jamie Madillad9f24e2016-02-12 09:27:24 -05002873 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002874
2875 Box area(xoffset, yoffset, 0, width, height, 1);
2876 Texture *texture =
2877 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002878 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002879 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002880}
2881
2882void Context::texSubImage3D(GLenum target,
2883 GLint level,
2884 GLint xoffset,
2885 GLint yoffset,
2886 GLint zoffset,
2887 GLsizei width,
2888 GLsizei height,
2889 GLsizei depth,
2890 GLenum format,
2891 GLenum type,
2892 const GLvoid *pixels)
2893{
2894 // Zero sized uploads are valid but no-ops
2895 if (width == 0 || height == 0 || depth == 0)
2896 {
2897 return;
2898 }
2899
Jamie Madillad9f24e2016-02-12 09:27:24 -05002900 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002901
2902 Box area(xoffset, yoffset, zoffset, width, height, depth);
2903 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002904 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002905 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002906}
2907
2908void Context::compressedTexImage2D(GLenum target,
2909 GLint level,
2910 GLenum internalformat,
2911 GLsizei width,
2912 GLsizei height,
2913 GLint border,
2914 GLsizei imageSize,
2915 const GLvoid *data)
2916{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002917 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002918
2919 Extents size(width, height, 1);
2920 Texture *texture =
2921 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002922 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2923 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002924 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002925}
2926
2927void Context::compressedTexImage3D(GLenum target,
2928 GLint level,
2929 GLenum internalformat,
2930 GLsizei width,
2931 GLsizei height,
2932 GLsizei depth,
2933 GLint border,
2934 GLsizei imageSize,
2935 const GLvoid *data)
2936{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002937 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002938
2939 Extents size(width, height, depth);
2940 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002941 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2942 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002943 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002944}
2945
2946void Context::compressedTexSubImage2D(GLenum target,
2947 GLint level,
2948 GLint xoffset,
2949 GLint yoffset,
2950 GLsizei width,
2951 GLsizei height,
2952 GLenum format,
2953 GLsizei imageSize,
2954 const GLvoid *data)
2955{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002956 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002957
2958 Box area(xoffset, yoffset, 0, width, height, 1);
2959 Texture *texture =
2960 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002961 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2962 format, imageSize,
2963 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002964}
2965
2966void Context::compressedTexSubImage3D(GLenum target,
2967 GLint level,
2968 GLint xoffset,
2969 GLint yoffset,
2970 GLint zoffset,
2971 GLsizei width,
2972 GLsizei height,
2973 GLsizei depth,
2974 GLenum format,
2975 GLsizei imageSize,
2976 const GLvoid *data)
2977{
2978 // Zero sized uploads are valid but no-ops
2979 if (width == 0 || height == 0)
2980 {
2981 return;
2982 }
2983
Jamie Madillad9f24e2016-02-12 09:27:24 -05002984 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002985
2986 Box area(xoffset, yoffset, zoffset, width, height, depth);
2987 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002988 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2989 format, imageSize,
2990 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002991}
2992
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002993void Context::generateMipmap(GLenum target)
2994{
2995 Texture *texture = getTargetTexture(target);
2996 handleError(texture->generateMipmap());
2997}
2998
Geoff Langc287ea62016-09-16 14:46:51 -04002999GLboolean Context::enableExtension(const char *name)
3000{
3001 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
3002 ASSERT(extensionInfos.find(name) != extensionInfos.end());
3003 const auto &extension = extensionInfos.at(name);
3004 ASSERT(extension.Enableable);
3005
3006 if (mExtensions.*(extension.ExtensionsMember))
3007 {
3008 // Extension already enabled
3009 return GL_TRUE;
3010 }
3011
3012 const auto &nativeExtensions = mImplementation->getNativeExtensions();
3013 if (!(nativeExtensions.*(extension.ExtensionsMember)))
3014 {
3015 // Underlying implementation does not support this valid extension
3016 return GL_FALSE;
3017 }
3018
3019 mExtensions.*(extension.ExtensionsMember) = true;
3020 updateCaps();
3021 initExtensionStrings();
3022 return GL_TRUE;
3023}
3024
Geoff Lang97073d12016-04-20 10:42:34 -07003025void Context::copyTextureCHROMIUM(GLuint sourceId,
3026 GLuint destId,
3027 GLint internalFormat,
3028 GLenum destType,
3029 GLboolean unpackFlipY,
3030 GLboolean unpackPremultiplyAlpha,
3031 GLboolean unpackUnmultiplyAlpha)
3032{
3033 syncStateForTexImage();
3034
3035 gl::Texture *sourceTexture = getTexture(sourceId);
3036 gl::Texture *destTexture = getTexture(destId);
3037 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3038 unpackPremultiplyAlpha == GL_TRUE,
3039 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3040}
3041
3042void Context::copySubTextureCHROMIUM(GLuint sourceId,
3043 GLuint destId,
3044 GLint xoffset,
3045 GLint yoffset,
3046 GLint x,
3047 GLint y,
3048 GLsizei width,
3049 GLsizei height,
3050 GLboolean unpackFlipY,
3051 GLboolean unpackPremultiplyAlpha,
3052 GLboolean unpackUnmultiplyAlpha)
3053{
3054 // Zero sized copies are valid but no-ops
3055 if (width == 0 || height == 0)
3056 {
3057 return;
3058 }
3059
3060 syncStateForTexImage();
3061
3062 gl::Texture *sourceTexture = getTexture(sourceId);
3063 gl::Texture *destTexture = getTexture(destId);
3064 Offset offset(xoffset, yoffset, 0);
3065 Rectangle area(x, y, width, height);
3066 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3067 unpackPremultiplyAlpha == GL_TRUE,
3068 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3069}
3070
Olli Etuaho4f667482016-03-30 15:56:35 +03003071void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
3072{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003073 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003074 ASSERT(buffer);
3075
3076 if (!buffer->isMapped())
3077 {
3078 *params = nullptr;
3079 }
3080 else
3081 {
3082 *params = buffer->getMapPointer();
3083 }
3084}
3085
3086GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3087{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003088 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003089 ASSERT(buffer);
3090
3091 Error error = buffer->map(access);
3092 if (error.isError())
3093 {
Jamie Madill437fa652016-05-03 15:13:24 -04003094 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003095 return nullptr;
3096 }
3097
3098 return buffer->getMapPointer();
3099}
3100
3101GLboolean Context::unmapBuffer(GLenum target)
3102{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003103 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003104 ASSERT(buffer);
3105
3106 GLboolean result;
3107 Error error = buffer->unmap(&result);
3108 if (error.isError())
3109 {
Jamie Madill437fa652016-05-03 15:13:24 -04003110 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003111 return GL_FALSE;
3112 }
3113
3114 return result;
3115}
3116
3117GLvoid *Context::mapBufferRange(GLenum target,
3118 GLintptr offset,
3119 GLsizeiptr length,
3120 GLbitfield access)
3121{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003122 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003123 ASSERT(buffer);
3124
3125 Error error = buffer->mapRange(offset, length, access);
3126 if (error.isError())
3127 {
Jamie Madill437fa652016-05-03 15:13:24 -04003128 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003129 return nullptr;
3130 }
3131
3132 return buffer->getMapPointer();
3133}
3134
3135void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3136{
3137 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3138}
3139
Jamie Madillad9f24e2016-02-12 09:27:24 -05003140void Context::syncStateForReadPixels()
3141{
3142 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3143}
3144
3145void Context::syncStateForTexImage()
3146{
3147 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3148}
3149
3150void Context::syncStateForClear()
3151{
3152 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3153}
3154
3155void Context::syncStateForBlit()
3156{
3157 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3158}
3159
Jamie Madillc20ab272016-06-09 07:20:46 -07003160void Context::activeTexture(GLenum texture)
3161{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003162 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003163}
3164
3165void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3166{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003167 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003168}
3169
3170void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3171{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003172 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003173}
3174
3175void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3176{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003177 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003178}
3179
3180void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3181{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003182 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003183}
3184
3185void Context::clearDepthf(GLclampf depth)
3186{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003187 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003188}
3189
3190void Context::clearStencil(GLint s)
3191{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003192 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003193}
3194
3195void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3196{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003197 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003198}
3199
3200void Context::cullFace(GLenum mode)
3201{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003202 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003203}
3204
3205void Context::depthFunc(GLenum func)
3206{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003207 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003208}
3209
3210void Context::depthMask(GLboolean flag)
3211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003212 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003213}
3214
3215void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003217 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003218}
3219
3220void Context::disable(GLenum cap)
3221{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003222 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003223}
3224
3225void Context::disableVertexAttribArray(GLuint index)
3226{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003227 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003228}
3229
3230void Context::enable(GLenum cap)
3231{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003232 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003233}
3234
3235void Context::enableVertexAttribArray(GLuint index)
3236{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003237 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003238}
3239
3240void Context::frontFace(GLenum mode)
3241{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003242 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003243}
3244
3245void Context::hint(GLenum target, GLenum mode)
3246{
3247 switch (target)
3248 {
3249 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003250 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003251 break;
3252
3253 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003254 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003255 break;
3256
3257 default:
3258 UNREACHABLE();
3259 return;
3260 }
3261}
3262
3263void Context::lineWidth(GLfloat width)
3264{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003265 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003266}
3267
3268void Context::pixelStorei(GLenum pname, GLint param)
3269{
3270 switch (pname)
3271 {
3272 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003273 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003274 break;
3275
3276 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003277 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003278 break;
3279
3280 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003281 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003282 break;
3283
3284 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003285 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003286 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003287 break;
3288
3289 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003290 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003291 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003292 break;
3293
3294 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003295 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003297 break;
3298
3299 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003300 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003301 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003302 break;
3303
3304 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003305 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003306 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003307 break;
3308
3309 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003310 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003311 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003312 break;
3313
3314 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003315 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003316 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003317 break;
3318
3319 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003320 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003321 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003322 break;
3323
3324 default:
3325 UNREACHABLE();
3326 return;
3327 }
3328}
3329
3330void Context::polygonOffset(GLfloat factor, GLfloat units)
3331{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003332 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003333}
3334
3335void Context::sampleCoverage(GLclampf value, GLboolean invert)
3336{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003337 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003338}
3339
3340void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3341{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003342 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003343}
3344
3345void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3346{
3347 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3348 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003350 }
3351
3352 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3353 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003355 }
3356}
3357
3358void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3359{
3360 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3361 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003362 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003363 }
3364
3365 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3366 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003367 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003368 }
3369}
3370
3371void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3372{
3373 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3374 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003375 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003376 }
3377
3378 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3379 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003380 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003381 }
3382}
3383
3384void Context::vertexAttrib1f(GLuint index, GLfloat x)
3385{
3386 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003387 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003388}
3389
3390void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3391{
3392 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003393 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003394}
3395
3396void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3397{
3398 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003400}
3401
3402void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3403{
3404 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003405 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003406}
3407
3408void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3409{
3410 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003411 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003412}
3413
3414void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3415{
3416 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003417 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003418}
3419
3420void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3421{
3422 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003423 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003424}
3425
3426void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3427{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003428 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003429}
3430
3431void Context::vertexAttribPointer(GLuint index,
3432 GLint size,
3433 GLenum type,
3434 GLboolean normalized,
3435 GLsizei stride,
3436 const GLvoid *ptr)
3437{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003438 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3439 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003440}
3441
3442void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3443{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003444 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003445}
3446
3447void Context::vertexAttribIPointer(GLuint index,
3448 GLint size,
3449 GLenum type,
3450 GLsizei stride,
3451 const GLvoid *pointer)
3452{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003453 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3454 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003455}
3456
3457void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3458{
3459 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003460 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003461}
3462
3463void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3464{
3465 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003466 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003467}
3468
3469void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3470{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003471 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003472}
3473
3474void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3475{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003476 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003477}
3478
3479void Context::debugMessageControl(GLenum source,
3480 GLenum type,
3481 GLenum severity,
3482 GLsizei count,
3483 const GLuint *ids,
3484 GLboolean enabled)
3485{
3486 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003487 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3488 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003489}
3490
3491void Context::debugMessageInsert(GLenum source,
3492 GLenum type,
3493 GLuint id,
3494 GLenum severity,
3495 GLsizei length,
3496 const GLchar *buf)
3497{
3498 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003499 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003500}
3501
3502void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3503{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003504 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003505}
3506
3507GLuint Context::getDebugMessageLog(GLuint count,
3508 GLsizei bufSize,
3509 GLenum *sources,
3510 GLenum *types,
3511 GLuint *ids,
3512 GLenum *severities,
3513 GLsizei *lengths,
3514 GLchar *messageLog)
3515{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003516 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3517 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003518}
3519
3520void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3521{
3522 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003523 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003524}
3525
3526void Context::popDebugGroup()
3527{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003528 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003529}
3530
Jamie Madill29639852016-09-02 15:00:09 -04003531void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3532{
3533 Buffer *buffer = mGLState.getTargetBuffer(target);
3534 ASSERT(buffer);
3535 handleError(buffer->bufferData(target, data, size, usage));
3536}
3537
3538void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3539{
3540 if (data == nullptr)
3541 {
3542 return;
3543 }
3544
3545 Buffer *buffer = mGLState.getTargetBuffer(target);
3546 ASSERT(buffer);
3547 handleError(buffer->bufferSubData(target, data, size, offset));
3548}
3549
Jamie Madillc29968b2016-01-20 11:17:23 -05003550} // namespace gl