blob: 3bdcc60ca7dfbd9544424a5ddf593c2d66e87462 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050021#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050022#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050029#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/ResourceManager.h"
31#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050032#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050033#include "libANGLE/Texture.h"
34#include "libANGLE/TransformFeedback.h"
35#include "libANGLE/VertexArray.h"
36#include "libANGLE/formatutils.h"
37#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070038#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040039#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040040#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030041#include "libANGLE/queryconversions.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000042
Geoff Langf6db0982015-08-25 13:04:00 -040043namespace
44{
45
Ian Ewell3ffd78b2016-01-22 16:09:42 -050046template <typename T>
Sami Väisänend59ca052016-06-21 16:10:00 +030047std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
48 GLsizei numPaths,
49 const void *paths,
50 GLuint pathBase)
51{
52 std::vector<gl::Path *> ret;
53 ret.reserve(numPaths);
54
55 const auto *nameArray = static_cast<const T *>(paths);
56
57 for (GLsizei i = 0; i < numPaths; ++i)
58 {
59 const GLuint pathName = nameArray[i] + pathBase;
60
61 ret.push_back(resourceManager.getPath(pathName));
62 }
63
64 return ret;
65}
66
67std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
68 GLsizei numPaths,
69 GLenum pathNameType,
70 const void *paths,
71 GLuint pathBase)
72{
73 switch (pathNameType)
74 {
75 case GL_UNSIGNED_BYTE:
76 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
77
78 case GL_BYTE:
79 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
80
81 case GL_UNSIGNED_SHORT:
82 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
83
84 case GL_SHORT:
85 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
86
87 case GL_UNSIGNED_INT:
88 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
89
90 case GL_INT:
91 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
92 }
93
94 UNREACHABLE();
95 return std::vector<gl::Path *>();
96}
97
98template <typename T>
Ian Ewell3ffd78b2016-01-22 16:09:42 -050099gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
100{
101 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
102 ASSERT(queryObject != nullptr);
103
104 switch (pname)
105 {
106 case GL_QUERY_RESULT_EXT:
107 return queryObject->getResult(params);
108 case GL_QUERY_RESULT_AVAILABLE_EXT:
109 {
110 bool available;
111 gl::Error error = queryObject->isResultAvailable(&available);
112 if (!error.isError())
113 {
114 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
115 }
116 return error;
117 }
118 default:
119 UNREACHABLE();
120 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
121 }
122}
123
Geoff Langf6db0982015-08-25 13:04:00 -0400124void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
125{
Geoff Lang1a683462015-09-29 15:09:59 -0400126 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400127 {
128 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
129 tfBufferIndex++)
130 {
131 const OffsetBindingPointer<gl::Buffer> &buffer =
132 transformFeedback->getIndexedBuffer(tfBufferIndex);
133 if (buffer.get() != nullptr)
134 {
135 buffer->onTransformFeedback();
136 }
137 }
138 }
139}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140
141// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300142EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500143{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400144 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500145}
146
Martin Radev1be913c2016-07-11 17:59:16 +0300147EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
148{
149 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
150}
151
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500152GLenum GetResetStrategy(const egl::AttributeMap &attribs)
153{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400154 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
155 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500156 switch (attrib)
157 {
158 case EGL_NO_RESET_NOTIFICATION:
159 return GL_NO_RESET_NOTIFICATION_EXT;
160 case EGL_LOSE_CONTEXT_ON_RESET:
161 return GL_LOSE_CONTEXT_ON_RESET_EXT;
162 default:
163 UNREACHABLE();
164 return GL_NONE;
165 }
166}
167
168bool GetRobustAccess(const egl::AttributeMap &attribs)
169{
170 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
171}
172
173bool GetDebug(const egl::AttributeMap &attribs)
174{
175 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
176}
177
178bool GetNoError(const egl::AttributeMap &attribs)
179{
180 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
181}
182
Geoff Langc287ea62016-09-16 14:46:51 -0400183bool GetWebGLContext(const egl::AttributeMap &attribs)
184{
185 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
186}
187
Geoff Langf41a7152016-09-19 15:11:17 -0400188bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
189{
190 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
191}
192
Martin Radev9d901792016-07-15 15:58:58 +0300193std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
194{
195 std::string labelName;
196 if (label != nullptr)
197 {
198 size_t labelLength = length < 0 ? strlen(label) : length;
199 labelName = std::string(label, labelLength);
200 }
201 return labelName;
202}
203
204void GetObjectLabelBase(const std::string &objectLabel,
205 GLsizei bufSize,
206 GLsizei *length,
207 GLchar *label)
208{
209 size_t writeLength = objectLabel.length();
210 if (label != nullptr && bufSize > 0)
211 {
212 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
213 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
214 label[writeLength] = '\0';
215 }
216
217 if (length != nullptr)
218 {
219 *length = static_cast<GLsizei>(writeLength);
220 }
221}
222
Geoff Langf6db0982015-08-25 13:04:00 -0400223} // anonymous namespace
224
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000225namespace gl
226{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000227
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400228Context::Context(rx::EGLImplFactory *implFactory,
229 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400230 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500231 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300232
233 : ValidationContext(GetClientMajorVersion(attribs),
234 GetClientMinorVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700235 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500236 mCaps,
237 mTextureCaps,
238 mExtensions,
239 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500240 mLimitations,
241 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700242 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500243 mCompiler(nullptr),
Martin Radev1be913c2016-07-11 17:59:16 +0300244 mClientMajorVersion(GetClientMajorVersion(attribs)),
245 mClientMinorVersion(GetClientMinorVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400246 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500247 mClientType(EGL_OPENGL_ES_API),
248 mHasBeenCurrent(false),
249 mContextLost(false),
250 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700251 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500252 mResetStrategy(GetResetStrategy(attribs)),
253 mRobustAccess(GetRobustAccess(attribs)),
254 mCurrentSurface(nullptr),
255 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000256{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500257 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000258
Geoff Langc287ea62016-09-16 14:46:51 -0400259 initCaps(GetWebGLContext(attribs));
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700260 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400261
Geoff Langf41a7152016-09-19 15:11:17 -0400262 mGLState.initialize(mCaps, mExtensions, mClientMajorVersion, GetDebug(attribs),
263 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100264
Shannon Woods53a94a82014-06-24 15:20:36 -0400265 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400266
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400267 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000268 {
269 mResourceManager = shareContext->mResourceManager;
270 mResourceManager->addRef();
271 }
272 else
273 {
Jamie Madill901b3792016-05-26 09:20:40 -0400274 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000275 }
276
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700277 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400278
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000279 // [OpenGL ES 2.0.24] section 3.7 page 83:
280 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
281 // and cube map texture state vectors respectively associated with them.
282 // In order that access to these initial textures not be lost, they are treated as texture
283 // objects all of whose names are 0.
284
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400285 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500286 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500287
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400288 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500289 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400290
Martin Radev1be913c2016-07-11 17:59:16 +0300291 if (mClientMajorVersion >= 3)
Geoff Lang76b10c92014-09-05 16:28:14 -0400292 {
293 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500298 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400299 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000300
Ian Ewellbda75592016-04-18 17:25:54 -0400301 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
302 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTextureExternal =
304 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400305 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
306 }
307
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700308 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500309
Jamie Madill57a89722013-07-02 11:57:03 -0400310 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000311 bindArrayBuffer(0);
312 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400313
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000314 bindRenderbuffer(0);
315
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000316 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400317 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000318 {
319 bindIndexedUniformBuffer(0, i, 0, -1);
320 }
321
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000322 bindCopyReadBuffer(0);
323 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000324 bindPixelPackBuffer(0);
325 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000326
Martin Radev1be913c2016-07-11 17:59:16 +0300327 if (mClientMajorVersion >= 3)
Geoff Lang1a683462015-09-29 15:09:59 -0400328 {
329 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
330 // In the initial state, a default transform feedback object is bound and treated as
331 // a transform feedback object with a name of zero. That object is bound any time
332 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400333 bindTransformFeedback(0);
334 }
Geoff Langc8058452014-02-03 12:04:11 -0500335
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700336 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500337
338 // Initialize dirty bit masks
339 // TODO(jmadill): additional ES3 state
340 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
341 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
342 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
343 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
344 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
345 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400346 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500347 // No dirty objects.
348
349 // Readpixels uses the pack state and read FBO
350 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
351 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
352 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
353 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
354 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400355 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500356 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
357
358 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
359 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
360 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
361 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
362 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
363 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
364 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
365 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
366 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
367 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
368 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
369 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
370
371 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
372 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
373 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
374 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400375
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400376 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000377}
378
379Context::~Context()
380{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700381 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000382
Corentin Wallez37c39792015-08-20 14:19:46 -0400383 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000384 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400385 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400386 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400387 {
388 SafeDelete(framebuffer.second);
389 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000390 }
391
Corentin Wallez80b24112015-08-25 16:41:57 -0400392 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000393 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400394 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395 }
396
Corentin Wallez80b24112015-08-25 16:41:57 -0400397 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000398 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400399 if (query.second != nullptr)
400 {
401 query.second->release();
402 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000403 }
404
Corentin Wallez80b24112015-08-25 16:41:57 -0400405 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400406 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400407 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400408 }
409
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500411 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500412 if (transformFeedback.second != nullptr)
413 {
414 transformFeedback.second->release();
415 }
Geoff Langc8058452014-02-03 12:04:11 -0500416 }
417
Jamie Madilldedd7b92014-11-05 16:30:36 -0500418 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400419 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500420 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400421 }
422 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423
Corentin Wallez51706ea2015-08-07 14:39:22 -0400424 if (mCurrentSurface != nullptr)
425 {
426 releaseSurface();
427 }
428
Jamie Madill1e9ae072014-11-06 15:27:21 -0500429 if (mResourceManager)
430 {
431 mResourceManager->release();
432 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500433
434 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435}
436
daniel@transgaming.comad629872012-11-28 19:32:06 +0000437void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438{
Jamie Madill77a72f62015-04-14 11:18:32 -0400439 ASSERT(surface != nullptr);
440
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000441 if (!mHasBeenCurrent)
442 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000443 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400444 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000445
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700446 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
447 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000448
449 mHasBeenCurrent = true;
450 }
451
Jamie Madill1b94d432015-08-07 13:23:23 -0400452 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700453 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400454
Corentin Wallez51706ea2015-08-07 14:39:22 -0400455 if (mCurrentSurface)
456 {
457 releaseSurface();
458 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000459 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400460 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000461
Corentin Wallez37c39792015-08-20 14:19:46 -0400462 // Update default framebuffer, the binding of the previous default
463 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400464 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400465 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700466 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400467 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700468 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400469 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700470 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400471 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700472 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400473 }
474 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400475 }
Ian Ewell292f0052016-02-04 10:37:32 -0500476
477 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700478 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000479}
480
Jamie Madill77a72f62015-04-14 11:18:32 -0400481void Context::releaseSurface()
482{
Corentin Wallez37c39792015-08-20 14:19:46 -0400483 ASSERT(mCurrentSurface != nullptr);
484
485 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400486 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400487 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700488 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400489 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700490 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400491 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700492 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400493 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700494 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400495 }
496 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400497 }
498
Corentin Wallez51706ea2015-08-07 14:39:22 -0400499 mCurrentSurface->setIsCurrent(false);
500 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400501}
502
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000503GLuint Context::createBuffer()
504{
505 return mResourceManager->createBuffer();
506}
507
508GLuint Context::createProgram()
509{
Jamie Madill901b3792016-05-26 09:20:40 -0400510 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000511}
512
513GLuint Context::createShader(GLenum type)
514{
Jamie Madill901b3792016-05-26 09:20:40 -0400515 return mResourceManager->createShader(mImplementation.get(),
516 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000517}
518
519GLuint Context::createTexture()
520{
521 return mResourceManager->createTexture();
522}
523
524GLuint Context::createRenderbuffer()
525{
526 return mResourceManager->createRenderbuffer();
527}
528
Geoff Lang882033e2014-09-30 11:26:07 -0400529GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400530{
Jamie Madill901b3792016-05-26 09:20:40 -0400531 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400532
Cooper Partind8e62a32015-01-29 15:21:25 -0800533 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400534}
535
Sami Väisänene45e53b2016-05-25 10:36:04 +0300536GLuint Context::createPaths(GLsizei range)
537{
538 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
539 if (resultOrError.isError())
540 {
541 handleError(resultOrError.getError());
542 return 0;
543 }
544 return resultOrError.getResult();
545}
546
Jamie Madill57a89722013-07-02 11:57:03 -0400547GLuint Context::createVertexArray()
548{
Geoff Lang36167ab2015-12-07 10:27:14 -0500549 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
550 mVertexArrayMap[vertexArray] = nullptr;
551 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400552}
553
Jamie Madilldc356042013-07-19 16:36:57 -0400554GLuint Context::createSampler()
555{
556 return mResourceManager->createSampler();
557}
558
Geoff Langc8058452014-02-03 12:04:11 -0500559GLuint Context::createTransformFeedback()
560{
Geoff Lang36167ab2015-12-07 10:27:14 -0500561 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
562 mTransformFeedbackMap[transformFeedback] = nullptr;
563 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500564}
565
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000566// Returns an unused framebuffer name
567GLuint Context::createFramebuffer()
568{
569 GLuint handle = mFramebufferHandleAllocator.allocate();
570
571 mFramebufferMap[handle] = NULL;
572
573 return handle;
574}
575
Jamie Madill33dc8432013-07-26 11:55:05 -0400576GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000577{
Jamie Madill33dc8432013-07-26 11:55:05 -0400578 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000579
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400580 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000581
582 return handle;
583}
584
585// Returns an unused query name
586GLuint Context::createQuery()
587{
588 GLuint handle = mQueryHandleAllocator.allocate();
589
590 mQueryMap[handle] = NULL;
591
592 return handle;
593}
594
595void Context::deleteBuffer(GLuint buffer)
596{
597 if (mResourceManager->getBuffer(buffer))
598 {
599 detachBuffer(buffer);
600 }
Jamie Madill893ab082014-05-16 16:56:10 -0400601
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000602 mResourceManager->deleteBuffer(buffer);
603}
604
605void Context::deleteShader(GLuint shader)
606{
607 mResourceManager->deleteShader(shader);
608}
609
610void Context::deleteProgram(GLuint program)
611{
612 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000613}
614
615void Context::deleteTexture(GLuint texture)
616{
617 if (mResourceManager->getTexture(texture))
618 {
619 detachTexture(texture);
620 }
621
622 mResourceManager->deleteTexture(texture);
623}
624
625void Context::deleteRenderbuffer(GLuint renderbuffer)
626{
627 if (mResourceManager->getRenderbuffer(renderbuffer))
628 {
629 detachRenderbuffer(renderbuffer);
630 }
Jamie Madill893ab082014-05-16 16:56:10 -0400631
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000632 mResourceManager->deleteRenderbuffer(renderbuffer);
633}
634
Jamie Madillcd055f82013-07-26 11:55:15 -0400635void Context::deleteFenceSync(GLsync fenceSync)
636{
637 // The spec specifies the underlying Fence object is not deleted until all current
638 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
639 // and since our API is currently designed for being called from a single thread, we can delete
640 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700641 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400642}
643
Sami Väisänene45e53b2016-05-25 10:36:04 +0300644void Context::deletePaths(GLuint first, GLsizei range)
645{
646 mResourceManager->deletePaths(first, range);
647}
648
649bool Context::hasPathData(GLuint path) const
650{
651 const auto *pathObj = mResourceManager->getPath(path);
652 if (pathObj == nullptr)
653 return false;
654
655 return pathObj->hasPathData();
656}
657
658bool Context::hasPath(GLuint path) const
659{
660 return mResourceManager->hasPath(path);
661}
662
663void Context::setPathCommands(GLuint path,
664 GLsizei numCommands,
665 const GLubyte *commands,
666 GLsizei numCoords,
667 GLenum coordType,
668 const void *coords)
669{
670 auto *pathObject = mResourceManager->getPath(path);
671
672 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
673}
674
675void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
676{
677 auto *pathObj = mResourceManager->getPath(path);
678
679 switch (pname)
680 {
681 case GL_PATH_STROKE_WIDTH_CHROMIUM:
682 pathObj->setStrokeWidth(value);
683 break;
684 case GL_PATH_END_CAPS_CHROMIUM:
685 pathObj->setEndCaps(static_cast<GLenum>(value));
686 break;
687 case GL_PATH_JOIN_STYLE_CHROMIUM:
688 pathObj->setJoinStyle(static_cast<GLenum>(value));
689 break;
690 case GL_PATH_MITER_LIMIT_CHROMIUM:
691 pathObj->setMiterLimit(value);
692 break;
693 case GL_PATH_STROKE_BOUND_CHROMIUM:
694 pathObj->setStrokeBound(value);
695 break;
696 default:
697 UNREACHABLE();
698 break;
699 }
700}
701
702void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
703{
704 const auto *pathObj = mResourceManager->getPath(path);
705
706 switch (pname)
707 {
708 case GL_PATH_STROKE_WIDTH_CHROMIUM:
709 *value = pathObj->getStrokeWidth();
710 break;
711 case GL_PATH_END_CAPS_CHROMIUM:
712 *value = static_cast<GLfloat>(pathObj->getEndCaps());
713 break;
714 case GL_PATH_JOIN_STYLE_CHROMIUM:
715 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
716 break;
717 case GL_PATH_MITER_LIMIT_CHROMIUM:
718 *value = pathObj->getMiterLimit();
719 break;
720 case GL_PATH_STROKE_BOUND_CHROMIUM:
721 *value = pathObj->getStrokeBound();
722 break;
723 default:
724 UNREACHABLE();
725 break;
726 }
727}
728
729void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
730{
731 mGLState.setPathStencilFunc(func, ref, mask);
732}
733
Jamie Madill57a89722013-07-02 11:57:03 -0400734void Context::deleteVertexArray(GLuint vertexArray)
735{
Geoff Lang36167ab2015-12-07 10:27:14 -0500736 auto iter = mVertexArrayMap.find(vertexArray);
737 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000738 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500739 VertexArray *vertexArrayObject = iter->second;
740 if (vertexArrayObject != nullptr)
741 {
742 detachVertexArray(vertexArray);
743 delete vertexArrayObject;
744 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000745
Geoff Lang36167ab2015-12-07 10:27:14 -0500746 mVertexArrayMap.erase(iter);
747 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400748 }
749}
750
Jamie Madilldc356042013-07-19 16:36:57 -0400751void Context::deleteSampler(GLuint sampler)
752{
753 if (mResourceManager->getSampler(sampler))
754 {
755 detachSampler(sampler);
756 }
757
758 mResourceManager->deleteSampler(sampler);
759}
760
Geoff Langc8058452014-02-03 12:04:11 -0500761void Context::deleteTransformFeedback(GLuint transformFeedback)
762{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500763 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500764 if (iter != mTransformFeedbackMap.end())
765 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500766 TransformFeedback *transformFeedbackObject = iter->second;
767 if (transformFeedbackObject != nullptr)
768 {
769 detachTransformFeedback(transformFeedback);
770 transformFeedbackObject->release();
771 }
772
Geoff Lang50b3fe82015-12-08 14:49:12 +0000773 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500774 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500775 }
776}
777
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000778void Context::deleteFramebuffer(GLuint framebuffer)
779{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500780 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000781
782 if (framebufferObject != mFramebufferMap.end())
783 {
784 detachFramebuffer(framebuffer);
785
786 mFramebufferHandleAllocator.release(framebufferObject->first);
787 delete framebufferObject->second;
788 mFramebufferMap.erase(framebufferObject);
789 }
790}
791
Jamie Madill33dc8432013-07-26 11:55:05 -0400792void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500794 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795
Jamie Madill33dc8432013-07-26 11:55:05 -0400796 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000797 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400798 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000799 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400800 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801 }
802}
803
804void Context::deleteQuery(GLuint query)
805{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500806 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000807 if (queryObject != mQueryMap.end())
808 {
809 mQueryHandleAllocator.release(queryObject->first);
810 if (queryObject->second)
811 {
812 queryObject->second->release();
813 }
814 mQueryMap.erase(queryObject);
815 }
816}
817
Geoff Lang70d0f492015-12-10 17:45:46 -0500818Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000819{
820 return mResourceManager->getBuffer(handle);
821}
822
Jamie Madill570f7c82014-07-03 10:38:54 -0400823Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000824{
825 return mResourceManager->getTexture(handle);
826}
827
Geoff Lang70d0f492015-12-10 17:45:46 -0500828Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000829{
830 return mResourceManager->getRenderbuffer(handle);
831}
832
Jamie Madillcd055f82013-07-26 11:55:15 -0400833FenceSync *Context::getFenceSync(GLsync handle) const
834{
Minmin Gong794e0002015-04-07 18:31:54 -0700835 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400836}
837
Jamie Madill57a89722013-07-02 11:57:03 -0400838VertexArray *Context::getVertexArray(GLuint handle) const
839{
840 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500841 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400842}
843
Jamie Madilldc356042013-07-19 16:36:57 -0400844Sampler *Context::getSampler(GLuint handle) const
845{
846 return mResourceManager->getSampler(handle);
847}
848
Geoff Langc8058452014-02-03 12:04:11 -0500849TransformFeedback *Context::getTransformFeedback(GLuint handle) const
850{
Geoff Lang36167ab2015-12-07 10:27:14 -0500851 auto iter = mTransformFeedbackMap.find(handle);
852 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500853}
854
Geoff Lang70d0f492015-12-10 17:45:46 -0500855LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
856{
857 switch (identifier)
858 {
859 case GL_BUFFER:
860 return getBuffer(name);
861 case GL_SHADER:
862 return getShader(name);
863 case GL_PROGRAM:
864 return getProgram(name);
865 case GL_VERTEX_ARRAY:
866 return getVertexArray(name);
867 case GL_QUERY:
868 return getQuery(name);
869 case GL_TRANSFORM_FEEDBACK:
870 return getTransformFeedback(name);
871 case GL_SAMPLER:
872 return getSampler(name);
873 case GL_TEXTURE:
874 return getTexture(name);
875 case GL_RENDERBUFFER:
876 return getRenderbuffer(name);
877 case GL_FRAMEBUFFER:
878 return getFramebuffer(name);
879 default:
880 UNREACHABLE();
881 return nullptr;
882 }
883}
884
885LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
886{
887 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
888}
889
Martin Radev9d901792016-07-15 15:58:58 +0300890void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
891{
892 LabeledObject *object = getLabeledObject(identifier, name);
893 ASSERT(object != nullptr);
894
895 std::string labelName = GetObjectLabelFromPointer(length, label);
896 object->setLabel(labelName);
897}
898
899void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
900{
901 LabeledObject *object = getLabeledObjectFromPtr(ptr);
902 ASSERT(object != nullptr);
903
904 std::string labelName = GetObjectLabelFromPointer(length, label);
905 object->setLabel(labelName);
906}
907
908void Context::getObjectLabel(GLenum identifier,
909 GLuint name,
910 GLsizei bufSize,
911 GLsizei *length,
912 GLchar *label) const
913{
914 LabeledObject *object = getLabeledObject(identifier, name);
915 ASSERT(object != nullptr);
916
917 const std::string &objectLabel = object->getLabel();
918 GetObjectLabelBase(objectLabel, bufSize, length, label);
919}
920
921void Context::getObjectPtrLabel(const void *ptr,
922 GLsizei bufSize,
923 GLsizei *length,
924 GLchar *label) const
925{
926 LabeledObject *object = getLabeledObjectFromPtr(ptr);
927 ASSERT(object != nullptr);
928
929 const std::string &objectLabel = object->getLabel();
930 GetObjectLabelBase(objectLabel, bufSize, length, label);
931}
932
Jamie Madilldc356042013-07-19 16:36:57 -0400933bool Context::isSampler(GLuint samplerName) const
934{
935 return mResourceManager->isSampler(samplerName);
936}
937
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500938void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000939{
Jamie Madill901b3792016-05-26 09:20:40 -0400940 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700941 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000942}
943
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500944void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000945{
Jamie Madill901b3792016-05-26 09:20:40 -0400946 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700947 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948}
949
Jamie Madilldedd7b92014-11-05 16:30:36 -0500950void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000951{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500952 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953
Jamie Madilldedd7b92014-11-05 16:30:36 -0500954 if (handle == 0)
955 {
956 texture = mZeroTextures[target].get();
957 }
958 else
959 {
Jamie Madill901b3792016-05-26 09:20:40 -0400960 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500961 }
962
963 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700964 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000965}
966
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500967void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000968{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500969 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700970 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000971}
972
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500973void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500975 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700976 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977}
978
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500979void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980{
Jamie Madill901b3792016-05-26 09:20:40 -0400981 Renderbuffer *renderbuffer =
982 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700983 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984}
985
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500986void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400987{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500988 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700989 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400990}
991
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500992void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400993{
Geoff Lang76b10c92014-09-05 16:28:14 -0400994 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400995 Sampler *sampler =
996 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700997 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400998}
999
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001000void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001001{
Jamie Madill901b3792016-05-26 09:20:40 -04001002 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001003 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001004}
1005
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001006void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1007 GLuint index,
1008 GLintptr offset,
1009 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001010{
Jamie Madill901b3792016-05-26 09:20:40 -04001011 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001012 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001013}
1014
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001015void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001016{
Jamie Madill901b3792016-05-26 09:20:40 -04001017 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001018 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001019}
1020
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001021void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1022 GLuint index,
1023 GLintptr offset,
1024 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001025{
Jamie Madill901b3792016-05-26 09:20:40 -04001026 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001028}
1029
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001030void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001031{
Jamie Madill901b3792016-05-26 09:20:40 -04001032 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001033 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001034}
1035
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001036void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001037{
Jamie Madill901b3792016-05-26 09:20:40 -04001038 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001039 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001040}
1041
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001042void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001043{
Jamie Madill901b3792016-05-26 09:20:40 -04001044 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001045 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001046}
1047
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001048void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001049{
Jamie Madill901b3792016-05-26 09:20:40 -04001050 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001051 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001052}
1053
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001054void Context::useProgram(GLuint program)
1055{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001056 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001057}
1058
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001059void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001060{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001061 TransformFeedback *transformFeedback =
1062 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001064}
1065
Geoff Lang5aad9672014-09-08 11:10:42 -04001066Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001067{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001069 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001070
Geoff Lang5aad9672014-09-08 11:10:42 -04001071 // begin query
1072 Error error = queryObject->begin();
1073 if (error.isError())
1074 {
1075 return error;
1076 }
1077
1078 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001079 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001080
Geoff Lang5aad9672014-09-08 11:10:42 -04001081 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001082}
1083
Geoff Lang5aad9672014-09-08 11:10:42 -04001084Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001086 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001087 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088
Geoff Lang5aad9672014-09-08 11:10:42 -04001089 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001090
Geoff Lang5aad9672014-09-08 11:10:42 -04001091 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001092 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001093
1094 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095}
1096
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001097Error Context::queryCounter(GLuint id, GLenum target)
1098{
1099 ASSERT(target == GL_TIMESTAMP_EXT);
1100
1101 Query *queryObject = getQuery(id, true, target);
1102 ASSERT(queryObject);
1103
1104 return queryObject->queryCounter();
1105}
1106
1107void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1108{
1109 switch (pname)
1110 {
1111 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001112 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001113 break;
1114 case GL_QUERY_COUNTER_BITS_EXT:
1115 switch (target)
1116 {
1117 case GL_TIME_ELAPSED_EXT:
1118 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1119 break;
1120 case GL_TIMESTAMP_EXT:
1121 params[0] = getExtensions().queryCounterBitsTimestamp;
1122 break;
1123 default:
1124 UNREACHABLE();
1125 params[0] = 0;
1126 break;
1127 }
1128 break;
1129 default:
1130 UNREACHABLE();
1131 return;
1132 }
1133}
1134
1135Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
1136{
1137 return GetQueryObjectParameter(this, id, pname, params);
1138}
1139
1140Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1141{
1142 return GetQueryObjectParameter(this, id, pname, params);
1143}
1144
1145Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
1146{
1147 return GetQueryObjectParameter(this, id, pname, params);
1148}
1149
1150Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
1151{
1152 return GetQueryObjectParameter(this, id, pname, params);
1153}
1154
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001155Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001156{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001157 auto framebufferIt = mFramebufferMap.find(handle);
1158 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001159}
1160
Jamie Madill33dc8432013-07-26 11:55:05 -04001161FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001162{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001163 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001164
Jamie Madill33dc8432013-07-26 11:55:05 -04001165 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001166 {
1167 return NULL;
1168 }
1169 else
1170 {
1171 return fence->second;
1172 }
1173}
1174
1175Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1176{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001177 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001178
1179 if (query == mQueryMap.end())
1180 {
1181 return NULL;
1182 }
1183 else
1184 {
1185 if (!query->second && create)
1186 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001187 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001188 query->second->addRef();
1189 }
1190 return query->second;
1191 }
1192}
1193
Geoff Lang70d0f492015-12-10 17:45:46 -05001194Query *Context::getQuery(GLuint handle) const
1195{
1196 auto iter = mQueryMap.find(handle);
1197 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1198}
1199
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001200Texture *Context::getTargetTexture(GLenum target) const
1201{
Ian Ewellbda75592016-04-18 17:25:54 -04001202 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001203 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001204}
1205
Geoff Lang76b10c92014-09-05 16:28:14 -04001206Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001207{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001208 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001209}
1210
Geoff Lang492a7e42014-11-05 13:27:06 -05001211Compiler *Context::getCompiler() const
1212{
1213 return mCompiler;
1214}
1215
Jamie Madill893ab082014-05-16 16:56:10 -04001216void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001217{
1218 switch (pname)
1219 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001220 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001221 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001222 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001223 mGLState.getBooleanv(pname, params);
1224 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226}
1227
Jamie Madill893ab082014-05-16 16:56:10 -04001228void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001229{
Shannon Woods53a94a82014-06-24 15:20:36 -04001230 // Queries about context capabilities and maximums are answered by Context.
1231 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232 switch (pname)
1233 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001234 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001235 params[0] = mCaps.minAliasedLineWidth;
1236 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237 break;
1238 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001239 params[0] = mCaps.minAliasedPointSize;
1240 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001242 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001243 ASSERT(mExtensions.textureFilterAnisotropic);
1244 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001245 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001246 case GL_MAX_TEXTURE_LOD_BIAS:
1247 *params = mCaps.maxLODBias;
1248 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001249
1250 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1251 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1252 {
1253 ASSERT(mExtensions.pathRendering);
1254 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1255 memcpy(params, m, 16 * sizeof(GLfloat));
1256 }
1257 break;
1258
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001259 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001260 mGLState.getFloatv(pname, params);
1261 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263}
1264
Jamie Madill893ab082014-05-16 16:56:10 -04001265void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266{
Shannon Woods53a94a82014-06-24 15:20:36 -04001267 // Queries about context capabilities and maximums are answered by Context.
1268 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001269
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270 switch (pname)
1271 {
Geoff Lang301d1612014-07-09 10:34:37 -04001272 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1273 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1274 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001275 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1276 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1277 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001278 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1279 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1280 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001281 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001282 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1283 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1284 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001285 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001286 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001287 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1288 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1289 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1290 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001291 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1292 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001293 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1294 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001295 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001296 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1297 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1298 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1299 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001300 case GL_MAJOR_VERSION:
1301 *params = mClientMajorVersion;
1302 break;
1303 case GL_MINOR_VERSION:
1304 *params = mClientMinorVersion;
1305 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001306 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1307 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001308 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1309 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1310 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001311 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1312 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1313 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001314 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001315 case GL_MAX_VIEWPORT_DIMS:
1316 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001317 params[0] = mCaps.maxViewportWidth;
1318 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001319 }
1320 break;
1321 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001322 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001323 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1325 *params = mResetStrategy;
1326 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001327 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001328 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001329 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001330 case GL_SHADER_BINARY_FORMATS:
1331 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1332 break;
1333 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001334 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001335 break;
1336 case GL_PROGRAM_BINARY_FORMATS:
1337 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001338 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001339 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001340 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001341 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001342
1343 // GL_KHR_debug
1344 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1345 *params = mExtensions.maxDebugMessageLength;
1346 break;
1347 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1348 *params = mExtensions.maxDebugLoggedMessages;
1349 break;
1350 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1351 *params = mExtensions.maxDebugGroupStackDepth;
1352 break;
1353 case GL_MAX_LABEL_LENGTH:
1354 *params = mExtensions.maxLabelLength;
1355 break;
1356
Ian Ewell53f59f42016-01-28 17:36:55 -05001357 // GL_EXT_disjoint_timer_query
1358 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001359 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001360 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001361 case GL_MAX_FRAMEBUFFER_WIDTH:
1362 *params = mCaps.maxFramebufferWidth;
1363 break;
1364 case GL_MAX_FRAMEBUFFER_HEIGHT:
1365 *params = mCaps.maxFramebufferHeight;
1366 break;
1367 case GL_MAX_FRAMEBUFFER_SAMPLES:
1368 *params = mCaps.maxFramebufferSamples;
1369 break;
1370 case GL_MAX_SAMPLE_MASK_WORDS:
1371 *params = mCaps.maxSampleMaskWords;
1372 break;
1373 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1374 *params = mCaps.maxColorTextureSamples;
1375 break;
1376 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1377 *params = mCaps.maxDepthTextureSamples;
1378 break;
1379 case GL_MAX_INTEGER_SAMPLES:
1380 *params = mCaps.maxIntegerSamples;
1381 break;
1382 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1383 *params = mCaps.maxVertexAttribRelativeOffset;
1384 break;
1385 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1386 *params = mCaps.maxVertexAttribBindings;
1387 break;
1388 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1389 *params = mCaps.maxVertexAttribStride;
1390 break;
1391 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1392 *params = mCaps.maxVertexAtomicCounterBuffers;
1393 break;
1394 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1395 *params = mCaps.maxVertexAtomicCounters;
1396 break;
1397 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1398 *params = mCaps.maxVertexImageUniforms;
1399 break;
1400 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1401 *params = mCaps.maxVertexShaderStorageBlocks;
1402 break;
1403 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1404 *params = mCaps.maxFragmentAtomicCounterBuffers;
1405 break;
1406 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1407 *params = mCaps.maxFragmentAtomicCounters;
1408 break;
1409 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1410 *params = mCaps.maxFragmentImageUniforms;
1411 break;
1412 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1413 *params = mCaps.maxFragmentShaderStorageBlocks;
1414 break;
1415 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1416 *params = mCaps.minProgramTextureGatherOffset;
1417 break;
1418 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1419 *params = mCaps.maxProgramTextureGatherOffset;
1420 break;
1421 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1422 *params = mCaps.maxComputeWorkGroupInvocations;
1423 break;
1424 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1425 *params = mCaps.maxComputeUniformBlocks;
1426 break;
1427 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1428 *params = mCaps.maxComputeTextureImageUnits;
1429 break;
1430 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1431 *params = mCaps.maxComputeSharedMemorySize;
1432 break;
1433 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1434 *params = mCaps.maxComputeUniformComponents;
1435 break;
1436 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1437 *params = mCaps.maxComputeAtomicCounterBuffers;
1438 break;
1439 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1440 *params = mCaps.maxComputeAtomicCounters;
1441 break;
1442 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1443 *params = mCaps.maxComputeImageUniforms;
1444 break;
1445 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1446 *params = mCaps.maxCombinedComputeUniformComponents;
1447 break;
1448 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1449 *params = mCaps.maxComputeShaderStorageBlocks;
1450 break;
1451 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1452 *params = mCaps.maxCombinedShaderOutputResources;
1453 break;
1454 case GL_MAX_UNIFORM_LOCATIONS:
1455 *params = mCaps.maxUniformLocations;
1456 break;
1457 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1458 *params = mCaps.maxAtomicCounterBufferBindings;
1459 break;
1460 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1461 *params = mCaps.maxAtomicCounterBufferSize;
1462 break;
1463 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1464 *params = mCaps.maxCombinedAtomicCounterBuffers;
1465 break;
1466 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1467 *params = mCaps.maxCombinedAtomicCounters;
1468 break;
1469 case GL_MAX_IMAGE_UNITS:
1470 *params = mCaps.maxImageUnits;
1471 break;
1472 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1473 *params = mCaps.maxCombinedImageUniforms;
1474 break;
1475 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1476 *params = mCaps.maxShaderStorageBufferBindings;
1477 break;
1478 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1479 *params = mCaps.maxCombinedShaderStorageBlocks;
1480 break;
1481 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1482 *params = mCaps.shaderStorageBufferOffsetAlignment;
1483 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001484 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001485 mGLState.getIntegerv(mState, pname, params);
1486 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001487 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001488}
1489
Jamie Madill893ab082014-05-16 16:56:10 -04001490void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001491{
Shannon Woods53a94a82014-06-24 15:20:36 -04001492 // Queries about context capabilities and maximums are answered by Context.
1493 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001494 switch (pname)
1495 {
1496 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001497 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001498 break;
1499 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001500 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001501 break;
1502 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001503 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001504 break;
1505 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001506 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001507 break;
1508 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001509 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001510 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001511
1512 // GL_EXT_disjoint_timer_query
1513 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001514 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001515 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001516
1517 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1518 *params = mCaps.maxShaderStorageBlockSize;
1519 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001520 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001521 UNREACHABLE();
1522 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001523 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001524}
1525
Geoff Lang70d0f492015-12-10 17:45:46 -05001526void Context::getPointerv(GLenum pname, void **params) const
1527{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001528 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001529}
1530
Martin Radev66fb8202016-07-28 11:45:20 +03001531void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001532{
Shannon Woods53a94a82014-06-24 15:20:36 -04001533 // Queries about context capabilities and maximums are answered by Context.
1534 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001535
1536 GLenum nativeType;
1537 unsigned int numParams;
1538 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001539 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001540 ASSERT(queryStatus);
1541
1542 if (nativeType == GL_INT)
1543 {
1544 switch (target)
1545 {
1546 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1547 ASSERT(index < 3u);
1548 *data = mCaps.maxComputeWorkGroupCount[index];
1549 break;
1550 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1551 ASSERT(index < 3u);
1552 *data = mCaps.maxComputeWorkGroupSize[index];
1553 break;
1554 default:
1555 mGLState.getIntegeri_v(target, index, data);
1556 }
1557 }
1558 else
1559 {
1560 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1561 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001562}
1563
Martin Radev66fb8202016-07-28 11:45:20 +03001564void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001565{
Shannon Woods53a94a82014-06-24 15:20:36 -04001566 // Queries about context capabilities and maximums are answered by Context.
1567 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001568
1569 GLenum nativeType;
1570 unsigned int numParams;
1571 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001572 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001573 ASSERT(queryStatus);
1574
1575 if (nativeType == GL_INT_64_ANGLEX)
1576 {
1577 mGLState.getInteger64i_v(target, index, data);
1578 }
1579 else
1580 {
1581 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1582 }
1583}
1584
1585void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1586{
1587 // Queries about context capabilities and maximums are answered by Context.
1588 // Queries about current GL state values are answered by State.
1589
1590 GLenum nativeType;
1591 unsigned int numParams;
1592 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001593 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001594 ASSERT(queryStatus);
1595
1596 if (nativeType == GL_BOOL)
1597 {
1598 mGLState.getBooleani_v(target, index, data);
1599 }
1600 else
1601 {
1602 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1603 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001604}
1605
Geoff Langf6db0982015-08-25 13:04:00 -04001606Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001607{
Jamie Madill1b94d432015-08-07 13:23:23 -04001608 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001609 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001610 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001611
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001612 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001613}
1614
Geoff Langf6db0982015-08-25 13:04:00 -04001615Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1616{
1617 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001618 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001619 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001620
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001621 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001622}
1623
1624Error Context::drawElements(GLenum mode,
1625 GLsizei count,
1626 GLenum type,
1627 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001628 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001629{
Jamie Madill1b94d432015-08-07 13:23:23 -04001630 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001631 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001632}
1633
1634Error Context::drawElementsInstanced(GLenum mode,
1635 GLsizei count,
1636 GLenum type,
1637 const GLvoid *indices,
1638 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001639 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001640{
1641 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001642 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1643 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001644}
1645
1646Error Context::drawRangeElements(GLenum mode,
1647 GLuint start,
1648 GLuint end,
1649 GLsizei count,
1650 GLenum type,
1651 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001652 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001653{
1654 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001655 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001656}
1657
Geoff Lang129753a2015-01-09 16:52:09 -05001658Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001659{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001660 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001661}
1662
1663Error Context::finish()
1664{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001665 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001666}
1667
Austin Kinross6ee1e782015-05-29 17:05:37 -07001668void Context::insertEventMarker(GLsizei length, const char *marker)
1669{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001670 ASSERT(mImplementation);
1671 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001672}
1673
1674void Context::pushGroupMarker(GLsizei length, const char *marker)
1675{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001676 ASSERT(mImplementation);
1677 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001678}
1679
1680void Context::popGroupMarker()
1681{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001682 ASSERT(mImplementation);
1683 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001684}
1685
Geoff Langd8605522016-04-13 10:19:12 -04001686void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1687{
1688 Program *programObject = getProgram(program);
1689 ASSERT(programObject);
1690
1691 programObject->bindUniformLocation(location, name);
1692}
1693
Sami Väisänena797e062016-05-12 15:23:40 +03001694void Context::setCoverageModulation(GLenum components)
1695{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001696 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001697}
1698
Sami Väisänene45e53b2016-05-25 10:36:04 +03001699void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1700{
1701 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1702}
1703
1704void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1705{
1706 GLfloat I[16];
1707 angle::Matrix<GLfloat>::setToIdentity(I);
1708
1709 mGLState.loadPathRenderingMatrix(matrixMode, I);
1710}
1711
1712void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1713{
1714 const auto *pathObj = mResourceManager->getPath(path);
1715 if (!pathObj)
1716 return;
1717
1718 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1719 syncRendererState();
1720
1721 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1722}
1723
1724void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1725{
1726 const auto *pathObj = mResourceManager->getPath(path);
1727 if (!pathObj)
1728 return;
1729
1730 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1731 syncRendererState();
1732
1733 mImplementation->stencilStrokePath(pathObj, reference, mask);
1734}
1735
1736void Context::coverFillPath(GLuint path, GLenum coverMode)
1737{
1738 const auto *pathObj = mResourceManager->getPath(path);
1739 if (!pathObj)
1740 return;
1741
1742 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1743 syncRendererState();
1744
1745 mImplementation->coverFillPath(pathObj, coverMode);
1746}
1747
1748void Context::coverStrokePath(GLuint path, GLenum coverMode)
1749{
1750 const auto *pathObj = mResourceManager->getPath(path);
1751 if (!pathObj)
1752 return;
1753
1754 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1755 syncRendererState();
1756
1757 mImplementation->coverStrokePath(pathObj, coverMode);
1758}
1759
1760void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1761{
1762 const auto *pathObj = mResourceManager->getPath(path);
1763 if (!pathObj)
1764 return;
1765
1766 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1767 syncRendererState();
1768
1769 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1770}
1771
1772void Context::stencilThenCoverStrokePath(GLuint path,
1773 GLint reference,
1774 GLuint mask,
1775 GLenum coverMode)
1776{
1777 const auto *pathObj = mResourceManager->getPath(path);
1778 if (!pathObj)
1779 return;
1780
1781 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1782 syncRendererState();
1783
1784 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1785}
1786
Sami Väisänend59ca052016-06-21 16:10:00 +03001787void Context::coverFillPathInstanced(GLsizei numPaths,
1788 GLenum pathNameType,
1789 const void *paths,
1790 GLuint pathBase,
1791 GLenum coverMode,
1792 GLenum transformType,
1793 const GLfloat *transformValues)
1794{
1795 const auto &pathObjects =
1796 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1797
1798 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1799 syncRendererState();
1800
1801 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1802}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001803
Sami Väisänend59ca052016-06-21 16:10:00 +03001804void Context::coverStrokePathInstanced(GLsizei numPaths,
1805 GLenum pathNameType,
1806 const void *paths,
1807 GLuint pathBase,
1808 GLenum coverMode,
1809 GLenum transformType,
1810 const GLfloat *transformValues)
1811{
1812 const auto &pathObjects =
1813 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1814
1815 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1816 syncRendererState();
1817
1818 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1819 transformValues);
1820}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001821
Sami Väisänend59ca052016-06-21 16:10:00 +03001822void Context::stencilFillPathInstanced(GLsizei numPaths,
1823 GLenum pathNameType,
1824 const void *paths,
1825 GLuint pathBase,
1826 GLenum fillMode,
1827 GLuint mask,
1828 GLenum transformType,
1829 const GLfloat *transformValues)
1830{
1831 const auto &pathObjects =
1832 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1833
1834 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1835 syncRendererState();
1836
1837 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1838 transformValues);
1839}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001840
Sami Väisänend59ca052016-06-21 16:10:00 +03001841void Context::stencilStrokePathInstanced(GLsizei numPaths,
1842 GLenum pathNameType,
1843 const void *paths,
1844 GLuint pathBase,
1845 GLint reference,
1846 GLuint mask,
1847 GLenum transformType,
1848 const GLfloat *transformValues)
1849{
1850 const auto &pathObjects =
1851 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1852
1853 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1854 syncRendererState();
1855
1856 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1857 transformValues);
1858}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001859
Sami Väisänend59ca052016-06-21 16:10:00 +03001860void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1861 GLenum pathNameType,
1862 const void *paths,
1863 GLuint pathBase,
1864 GLenum fillMode,
1865 GLuint mask,
1866 GLenum coverMode,
1867 GLenum transformType,
1868 const GLfloat *transformValues)
1869{
1870 const auto &pathObjects =
1871 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1872
1873 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1874 syncRendererState();
1875
1876 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1877 transformType, transformValues);
1878}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001879
Sami Väisänend59ca052016-06-21 16:10:00 +03001880void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1881 GLenum pathNameType,
1882 const void *paths,
1883 GLuint pathBase,
1884 GLint reference,
1885 GLuint mask,
1886 GLenum coverMode,
1887 GLenum transformType,
1888 const GLfloat *transformValues)
1889{
1890 const auto &pathObjects =
1891 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1892
1893 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1894 syncRendererState();
1895
1896 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1897 transformType, transformValues);
1898}
1899
Sami Väisänen46eaa942016-06-29 10:26:37 +03001900void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1901{
1902 auto *programObject = getProgram(program);
1903
1904 programObject->bindFragmentInputLocation(location, name);
1905}
1906
1907void Context::programPathFragmentInputGen(GLuint program,
1908 GLint location,
1909 GLenum genMode,
1910 GLint components,
1911 const GLfloat *coeffs)
1912{
1913 auto *programObject = getProgram(program);
1914
1915 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1916}
1917
Jamie Madill437fa652016-05-03 15:13:24 -04001918void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001919{
Geoff Langda5777c2014-07-11 09:52:58 -04001920 if (error.isError())
1921 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001922 GLenum code = error.getCode();
1923 mErrors.insert(code);
1924 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1925 {
1926 markContextLost();
1927 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001928
1929 if (!error.getMessage().empty())
1930 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001931 auto *debug = &mGLState.getDebug();
1932 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1933 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001934 }
Geoff Langda5777c2014-07-11 09:52:58 -04001935 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001936}
1937
1938// Get one of the recorded errors and clear its flag, if any.
1939// [OpenGL ES 2.0.24] section 2.5 page 13.
1940GLenum Context::getError()
1941{
Geoff Langda5777c2014-07-11 09:52:58 -04001942 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001943 {
Geoff Langda5777c2014-07-11 09:52:58 -04001944 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001945 }
Geoff Langda5777c2014-07-11 09:52:58 -04001946 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001947 {
Geoff Langda5777c2014-07-11 09:52:58 -04001948 GLenum error = *mErrors.begin();
1949 mErrors.erase(mErrors.begin());
1950 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001951 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001952}
1953
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001954// NOTE: this function should not assume that this context is current!
1955void Context::markContextLost()
1956{
1957 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001958 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001959 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001960 mContextLostForced = true;
1961 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001962 mContextLost = true;
1963}
1964
1965bool Context::isContextLost()
1966{
1967 return mContextLost;
1968}
1969
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001970GLenum Context::getResetStatus()
1971{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001972 // Even if the application doesn't want to know about resets, we want to know
1973 // as it will allow us to skip all the calls.
1974 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001975 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001976 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001977 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001978 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001979 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001980
1981 // EXT_robustness, section 2.6: If the reset notification behavior is
1982 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1983 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1984 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001985 }
1986
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001987 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1988 // status should be returned at least once, and GL_NO_ERROR should be returned
1989 // once the device has finished resetting.
1990 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001991 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001992 ASSERT(mResetStatus == GL_NO_ERROR);
1993 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001994
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001995 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001996 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001997 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001998 }
1999 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002000 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002001 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002002 // If markContextLost was used to mark the context lost then
2003 // assume that is not recoverable, and continue to report the
2004 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002005 mResetStatus = mImplementation->getResetStatus();
2006 }
Jamie Madill893ab082014-05-16 16:56:10 -04002007
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002008 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002009}
2010
2011bool Context::isResetNotificationEnabled()
2012{
2013 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2014}
2015
Corentin Walleze3b10e82015-05-20 11:06:25 -04002016const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002017{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002018 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002019}
2020
2021EGLenum Context::getClientType() const
2022{
2023 return mClientType;
2024}
2025
2026EGLenum Context::getRenderBuffer() const
2027{
Corentin Wallez37c39792015-08-20 14:19:46 -04002028 auto framebufferIt = mFramebufferMap.find(0);
2029 if (framebufferIt != mFramebufferMap.end())
2030 {
2031 const Framebuffer *framebuffer = framebufferIt->second;
2032 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2033
2034 ASSERT(backAttachment != nullptr);
2035 return backAttachment->getSurface()->getRenderBuffer();
2036 }
2037 else
2038 {
2039 return EGL_NONE;
2040 }
Régis Fénéon83107972015-02-05 12:57:44 +01002041}
2042
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002043VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002044{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002045 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002046 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2047 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002048 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002049 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002051 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002052 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002053
2054 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002055}
2056
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002057TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002058{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002059 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002060 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2061 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002062 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002063 transformFeedback =
2064 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002065 transformFeedback->addRef();
2066 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002067 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002068
2069 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002070}
2071
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002072Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2073{
2074 // Can be called from Bind without a prior call to Gen.
2075 auto framebufferIt = mFramebufferMap.find(framebuffer);
2076 bool neverCreated = framebufferIt == mFramebufferMap.end();
2077 if (neverCreated || framebufferIt->second == nullptr)
2078 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002079 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002080 if (neverCreated)
2081 {
2082 mFramebufferHandleAllocator.reserve(framebuffer);
2083 mFramebufferMap[framebuffer] = newFBO;
2084 return newFBO;
2085 }
2086
2087 framebufferIt->second = newFBO;
2088 }
2089
2090 return framebufferIt->second;
2091}
2092
Geoff Langf41a7152016-09-19 15:11:17 -04002093bool Context::isTextureGenerated(GLuint texture) const
2094{
2095 return mResourceManager->isTextureGenerated(texture);
2096}
2097
2098bool Context::isBufferGenerated(GLuint buffer) const
2099{
2100 return mResourceManager->isBufferGenerated(buffer);
2101}
2102
2103bool Context::isRenderbufferGenerated(GLuint renderbuffer) const
2104{
2105 return mResourceManager->isRenderbufferGenerated(renderbuffer);
2106}
2107
2108bool Context::isFramebufferGenerated(GLuint framebuffer) const
2109{
2110 ASSERT(mFramebufferMap.find(0) != mFramebufferMap.end());
2111 return mFramebufferMap.find(framebuffer) != mFramebufferMap.end();
2112}
2113
Geoff Lang36167ab2015-12-07 10:27:14 -05002114bool Context::isVertexArrayGenerated(GLuint vertexArray)
2115{
Geoff Langf41a7152016-09-19 15:11:17 -04002116 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002117 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2118}
2119
2120bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2121{
Geoff Langf41a7152016-09-19 15:11:17 -04002122 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002123 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2124}
2125
Shannon Woods53a94a82014-06-24 15:20:36 -04002126void Context::detachTexture(GLuint texture)
2127{
2128 // Simple pass-through to State's detachTexture method, as textures do not require
2129 // allocation map management either here or in the resource manager at detach time.
2130 // Zero textures are held by the Context, and we don't attempt to request them from
2131 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002132 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002133}
2134
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002135void Context::detachBuffer(GLuint buffer)
2136{
Yuly Novikov5807a532015-12-03 13:01:22 -05002137 // Simple pass-through to State's detachBuffer method, since
2138 // only buffer attachments to container objects that are bound to the current context
2139 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002140
Yuly Novikov5807a532015-12-03 13:01:22 -05002141 // [OpenGL ES 3.2] section 5.1.2 page 45:
2142 // Attachments to unbound container objects, such as
2143 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2144 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002145 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002146}
2147
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002148void Context::detachFramebuffer(GLuint framebuffer)
2149{
Shannon Woods53a94a82014-06-24 15:20:36 -04002150 // Framebuffer detachment is handled by Context, because 0 is a valid
2151 // Framebuffer object, and a pointer to it must be passed from Context
2152 // to State at binding time.
2153
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002154 // [OpenGL ES 2.0.24] section 4.4 page 107:
2155 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2156 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2157
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002158 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002159 {
2160 bindReadFramebuffer(0);
2161 }
2162
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002163 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002164 {
2165 bindDrawFramebuffer(0);
2166 }
2167}
2168
2169void Context::detachRenderbuffer(GLuint renderbuffer)
2170{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002171 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002172}
2173
Jamie Madill57a89722013-07-02 11:57:03 -04002174void Context::detachVertexArray(GLuint vertexArray)
2175{
Jamie Madill77a72f62015-04-14 11:18:32 -04002176 // Vertex array detachment is handled by Context, because 0 is a valid
2177 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002178 // binding time.
2179
Jamie Madill57a89722013-07-02 11:57:03 -04002180 // [OpenGL ES 3.0.2] section 2.10 page 43:
2181 // If a vertex array object that is currently bound is deleted, the binding
2182 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002183 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002184 {
2185 bindVertexArray(0);
2186 }
2187}
2188
Geoff Langc8058452014-02-03 12:04:11 -05002189void Context::detachTransformFeedback(GLuint transformFeedback)
2190{
Corentin Walleza2257da2016-04-19 16:43:12 -04002191 // Transform feedback detachment is handled by Context, because 0 is a valid
2192 // transform feedback, and a pointer to it must be passed from Context to State at
2193 // binding time.
2194
2195 // The OpenGL specification doesn't mention what should happen when the currently bound
2196 // transform feedback object is deleted. Since it is a container object, we treat it like
2197 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002198 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002199 {
2200 bindTransformFeedback(0);
2201 }
Geoff Langc8058452014-02-03 12:04:11 -05002202}
2203
Jamie Madilldc356042013-07-19 16:36:57 -04002204void Context::detachSampler(GLuint sampler)
2205{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002206 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002207}
2208
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002209void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2210{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002211 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002212}
2213
Jamie Madille29d1672013-07-19 16:36:57 -04002214void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2215{
Jamie Madill901b3792016-05-26 09:20:40 -04002216 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002217
2218 Sampler *samplerObject = getSampler(sampler);
2219 ASSERT(samplerObject);
2220
Geoff Lang69cce582015-09-17 13:20:36 -04002221 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002222 switch (pname)
2223 {
Geoff Lang69cce582015-09-17 13:20:36 -04002224 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
2225 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
2226 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
2227 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
2228 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
2229 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
2230 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
2231 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
2232 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
2233 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
2234 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002235 }
Geoff Lang69cce582015-09-17 13:20:36 -04002236 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002237}
2238
2239void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2240{
Jamie Madill901b3792016-05-26 09:20:40 -04002241 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002242
2243 Sampler *samplerObject = getSampler(sampler);
2244 ASSERT(samplerObject);
2245
Geoff Lang69cce582015-09-17 13:20:36 -04002246 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002247 switch (pname)
2248 {
Geoff Lang69cce582015-09-17 13:20:36 -04002249 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
2250 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
2251 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
2252 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
2253 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
2254 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
2255 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
2256 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
2257 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
2258 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
2259 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002260 }
Geoff Lang69cce582015-09-17 13:20:36 -04002261 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002262}
2263
Jamie Madill9675b802013-07-19 16:36:59 -04002264GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
2265{
Jamie Madill901b3792016-05-26 09:20:40 -04002266 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002267
2268 Sampler *samplerObject = getSampler(sampler);
2269 ASSERT(samplerObject);
2270
Geoff Lang69cce582015-09-17 13:20:36 -04002271 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002272 switch (pname)
2273 {
Geoff Lang69cce582015-09-17 13:20:36 -04002274 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
2275 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
2276 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
2277 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
2278 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
2279 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02002280 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
2281 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04002282 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
2283 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
2284 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002285 }
Geoff Lang69cce582015-09-17 13:20:36 -04002286 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002287}
2288
2289GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
2290{
Jamie Madill901b3792016-05-26 09:20:40 -04002291 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002292
2293 Sampler *samplerObject = getSampler(sampler);
2294 ASSERT(samplerObject);
2295
Geoff Lang69cce582015-09-17 13:20:36 -04002296 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002297 switch (pname)
2298 {
Geoff Lang69cce582015-09-17 13:20:36 -04002299 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
2300 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
2301 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
2302 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2303 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2304 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
2305 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2306 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2307 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2308 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2309 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002310 }
Geoff Lang69cce582015-09-17 13:20:36 -04002311 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002312}
2313
Olli Etuahof0fee072016-03-30 15:11:58 +03002314void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2315{
2316 gl::Program *programObject = getProgram(program);
2317 ASSERT(programObject != nullptr);
2318
2319 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2320 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2321}
2322
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002323void Context::initRendererString()
2324{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002325 std::ostringstream rendererString;
2326 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002327 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002328 rendererString << ")";
2329
Geoff Langcec35902014-04-16 10:52:36 -04002330 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002331}
2332
Geoff Langc287ea62016-09-16 14:46:51 -04002333const char *Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002334{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002335 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002336}
2337
Geoff Langcec35902014-04-16 10:52:36 -04002338void Context::initExtensionStrings()
2339{
Geoff Langc287ea62016-09-16 14:46:51 -04002340 for (const auto &extensionString : mExtensions.getStrings())
2341 {
2342 mExtensionStrings.push_back(MakeStaticString(extensionString));
2343 }
Geoff Langcec35902014-04-16 10:52:36 -04002344
Geoff Langc0b9ef42014-07-02 10:02:37 -04002345 std::ostringstream combinedStringStream;
Geoff Langc287ea62016-09-16 14:46:51 -04002346 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(),
2347 std::ostream_iterator<const char *>(combinedStringStream, " "));
2348 mExtensionString = MakeStaticString(combinedStringStream.str());
Geoff Langcec35902014-04-16 10:52:36 -04002349}
2350
Geoff Langc287ea62016-09-16 14:46:51 -04002351const char *Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002352{
2353 return mExtensionString;
2354}
2355
Geoff Langc287ea62016-09-16 14:46:51 -04002356const char *Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002357{
2358 return mExtensionStrings[idx];
2359}
2360
2361size_t Context::getExtensionStringCount() const
2362{
2363 return mExtensionStrings.size();
2364}
2365
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002366void Context::beginTransformFeedback(GLenum primitiveMode)
2367{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002368 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002369 ASSERT(transformFeedback != nullptr);
2370 ASSERT(!transformFeedback->isPaused());
2371
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002372 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002373}
2374
2375bool Context::hasActiveTransformFeedback(GLuint program) const
2376{
2377 for (auto pair : mTransformFeedbackMap)
2378 {
2379 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2380 {
2381 return true;
2382 }
2383 }
2384 return false;
2385}
2386
Geoff Langc287ea62016-09-16 14:46:51 -04002387void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002388{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002389 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002390
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002391 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002392
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002393 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002394
Martin Radev1be913c2016-07-11 17:59:16 +03002395 if (mClientMajorVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002396 {
2397 // Disable ES3+ extensions
2398 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002399 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002400 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002401 }
2402
Martin Radev1be913c2016-07-11 17:59:16 +03002403 if (mClientMajorVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002404 {
2405 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2406 //mExtensions.sRGB = false;
2407 }
2408
Jamie Madill00ed7a12016-05-19 13:13:38 -04002409 // Some extensions are always available because they are implemented in the GL layer.
2410 mExtensions.bindUniformLocation = true;
2411 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002412 mExtensions.bindGeneratesResource = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002413
2414 // Enable the no error extension if the context was created with the flag.
2415 mExtensions.noError = mSkipValidation;
2416
Geoff Lang70d0f492015-12-10 17:45:46 -05002417 // Explicitly enable GL_KHR_debug
2418 mExtensions.debug = true;
2419 mExtensions.maxDebugMessageLength = 1024;
2420 mExtensions.maxDebugLoggedMessages = 1024;
2421 mExtensions.maxDebugGroupStackDepth = 1024;
2422 mExtensions.maxLabelLength = 1024;
2423
Geoff Langff5b2d52016-09-07 11:32:23 -04002424 // Explicitly enable GL_ANGLE_robust_client_memory
2425 mExtensions.robustClientMemory = true;
2426
Geoff Lang301d1612014-07-09 10:34:37 -04002427 // Apply implementation limits
2428 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002429 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2430 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2431
2432 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002433
Geoff Langc287ea62016-09-16 14:46:51 -04002434 // WebGL compatibility
2435 mExtensions.webglCompatibility = webGLContext;
2436 for (const auto &extensionInfo : GetExtensionInfoMap())
2437 {
2438 // If this context is for WebGL, disable all enableable extensions
2439 if (webGLContext && extensionInfo.second.Enableable)
2440 {
2441 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2442 }
2443 }
2444
2445 // Generate texture caps
2446 updateCaps();
2447}
2448
2449void Context::updateCaps()
2450{
Geoff Lang900013c2014-07-07 11:32:19 -04002451 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002452 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002453
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002454 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002455 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2456 {
2457 GLenum format = i->first;
2458 TextureCaps formatCaps = i->second;
2459
Geoff Lang5d601382014-07-22 15:14:06 -04002460 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002461
Geoff Lang0d8b7242015-09-09 14:56:53 -04002462 // Update the format caps based on the client version and extensions.
2463 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2464 // ES3.
2465 formatCaps.texturable =
Martin Radev1be913c2016-07-11 17:59:16 +03002466 formatCaps.texturable && formatInfo.textureSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002467 formatCaps.renderable =
Martin Radev1be913c2016-07-11 17:59:16 +03002468 formatCaps.renderable && formatInfo.renderSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002469 formatCaps.filterable =
Martin Radev1be913c2016-07-11 17:59:16 +03002470 formatCaps.filterable && formatInfo.filterSupport(mClientMajorVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002471
2472 // OpenGL ES does not support multisampling with integer formats
2473 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002474 {
Geoff Langd87878e2014-09-19 15:42:59 -04002475 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002476 }
Geoff Langd87878e2014-09-19 15:42:59 -04002477
2478 if (formatCaps.texturable && formatInfo.compressed)
2479 {
2480 mCaps.compressedTextureFormats.push_back(format);
2481 }
2482
2483 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002484 }
2485}
2486
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002487void Context::initWorkarounds()
2488{
2489 // Lose the context upon out of memory error if the application is
2490 // expecting to watch for those events.
2491 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2492}
2493
Jamie Madill1b94d432015-08-07 13:23:23 -04002494void Context::syncRendererState()
2495{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002496 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2497 mImplementation->syncState(mGLState, dirtyBits);
2498 mGLState.clearDirtyBits();
2499 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002500}
2501
Jamie Madillad9f24e2016-02-12 09:27:24 -05002502void Context::syncRendererState(const State::DirtyBits &bitMask,
2503 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002504{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002505 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2506 mImplementation->syncState(mGLState, dirtyBits);
2507 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002508
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002509 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002510}
Jamie Madillc29968b2016-01-20 11:17:23 -05002511
2512void Context::blitFramebuffer(GLint srcX0,
2513 GLint srcY0,
2514 GLint srcX1,
2515 GLint srcY1,
2516 GLint dstX0,
2517 GLint dstY0,
2518 GLint dstX1,
2519 GLint dstY1,
2520 GLbitfield mask,
2521 GLenum filter)
2522{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002523 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002524 ASSERT(drawFramebuffer);
2525
2526 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2527 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2528
Jamie Madillad9f24e2016-02-12 09:27:24 -05002529 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002530
Jamie Madill8415b5f2016-04-26 13:41:39 -04002531 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002532}
Jamie Madillc29968b2016-01-20 11:17:23 -05002533
2534void Context::clear(GLbitfield mask)
2535{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002536 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002537 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002538}
2539
2540void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2541{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002542 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002543 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2544 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002545}
2546
2547void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2548{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002549 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002550 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2551 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002552}
2553
2554void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2555{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002556 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002557 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2558 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002559}
2560
2561void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2562{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002563 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002564 ASSERT(framebufferObject);
2565
2566 // If a buffer is not present, the clear has no effect
2567 if (framebufferObject->getDepthbuffer() == nullptr &&
2568 framebufferObject->getStencilbuffer() == nullptr)
2569 {
2570 return;
2571 }
2572
Jamie Madillad9f24e2016-02-12 09:27:24 -05002573 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002574 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2575 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002576}
2577
2578void Context::readPixels(GLint x,
2579 GLint y,
2580 GLsizei width,
2581 GLsizei height,
2582 GLenum format,
2583 GLenum type,
2584 GLvoid *pixels)
2585{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002586 if (width == 0 || height == 0)
2587 {
2588 return;
2589 }
2590
Jamie Madillad9f24e2016-02-12 09:27:24 -05002591 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002592
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002593 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002594 ASSERT(framebufferObject);
2595
2596 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002597 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002598}
2599
2600void Context::copyTexImage2D(GLenum target,
2601 GLint level,
2602 GLenum internalformat,
2603 GLint x,
2604 GLint y,
2605 GLsizei width,
2606 GLsizei height,
2607 GLint border)
2608{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002609 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002610 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002611
Jamie Madillc29968b2016-01-20 11:17:23 -05002612 Rectangle sourceArea(x, y, width, height);
2613
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002614 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002615 Texture *texture =
2616 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002617 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002618}
2619
2620void Context::copyTexSubImage2D(GLenum target,
2621 GLint level,
2622 GLint xoffset,
2623 GLint yoffset,
2624 GLint x,
2625 GLint y,
2626 GLsizei width,
2627 GLsizei height)
2628{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002629 if (width == 0 || height == 0)
2630 {
2631 return;
2632 }
2633
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002634 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002635 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002636
Jamie Madillc29968b2016-01-20 11:17:23 -05002637 Offset destOffset(xoffset, yoffset, 0);
2638 Rectangle sourceArea(x, y, width, height);
2639
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002640 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002641 Texture *texture =
2642 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002643 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002644}
2645
2646void Context::copyTexSubImage3D(GLenum target,
2647 GLint level,
2648 GLint xoffset,
2649 GLint yoffset,
2650 GLint zoffset,
2651 GLint x,
2652 GLint y,
2653 GLsizei width,
2654 GLsizei height)
2655{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002656 if (width == 0 || height == 0)
2657 {
2658 return;
2659 }
2660
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002661 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002662 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002663
Jamie Madillc29968b2016-01-20 11:17:23 -05002664 Offset destOffset(xoffset, yoffset, zoffset);
2665 Rectangle sourceArea(x, y, width, height);
2666
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002667 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002668 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002669 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002670}
2671
2672void Context::framebufferTexture2D(GLenum target,
2673 GLenum attachment,
2674 GLenum textarget,
2675 GLuint texture,
2676 GLint level)
2677{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002678 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002679 ASSERT(framebuffer);
2680
2681 if (texture != 0)
2682 {
2683 Texture *textureObj = getTexture(texture);
2684
2685 ImageIndex index = ImageIndex::MakeInvalid();
2686
2687 if (textarget == GL_TEXTURE_2D)
2688 {
2689 index = ImageIndex::Make2D(level);
2690 }
2691 else
2692 {
2693 ASSERT(IsCubeMapTextureTarget(textarget));
2694 index = ImageIndex::MakeCube(textarget, level);
2695 }
2696
2697 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2698 }
2699 else
2700 {
2701 framebuffer->resetAttachment(attachment);
2702 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002703
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002704 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002705}
2706
2707void Context::framebufferRenderbuffer(GLenum target,
2708 GLenum attachment,
2709 GLenum renderbuffertarget,
2710 GLuint renderbuffer)
2711{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002712 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002713 ASSERT(framebuffer);
2714
2715 if (renderbuffer != 0)
2716 {
2717 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2718 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2719 renderbufferObject);
2720 }
2721 else
2722 {
2723 framebuffer->resetAttachment(attachment);
2724 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002725
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002726 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002727}
2728
2729void Context::framebufferTextureLayer(GLenum target,
2730 GLenum attachment,
2731 GLuint texture,
2732 GLint level,
2733 GLint layer)
2734{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002735 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002736 ASSERT(framebuffer);
2737
2738 if (texture != 0)
2739 {
2740 Texture *textureObject = getTexture(texture);
2741
2742 ImageIndex index = ImageIndex::MakeInvalid();
2743
2744 if (textureObject->getTarget() == GL_TEXTURE_3D)
2745 {
2746 index = ImageIndex::Make3D(level, layer);
2747 }
2748 else
2749 {
2750 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2751 index = ImageIndex::Make2DArray(level, layer);
2752 }
2753
2754 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2755 }
2756 else
2757 {
2758 framebuffer->resetAttachment(attachment);
2759 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002760
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002761 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002762}
2763
2764void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2765{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002766 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002767 ASSERT(framebuffer);
2768 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002769 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002770}
2771
2772void Context::readBuffer(GLenum mode)
2773{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002774 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002775 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002776 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002777}
2778
2779void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2780{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002781 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002782 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002783
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002784 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002785 ASSERT(framebuffer);
2786
2787 // The specification isn't clear what should be done when the framebuffer isn't complete.
2788 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002789 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002790}
2791
2792void Context::invalidateFramebuffer(GLenum target,
2793 GLsizei numAttachments,
2794 const GLenum *attachments)
2795{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002796 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002797 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002798
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002799 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002800 ASSERT(framebuffer);
2801
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002802 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002803 {
Jamie Madill437fa652016-05-03 15:13:24 -04002804 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002805 }
Jamie Madill437fa652016-05-03 15:13:24 -04002806
2807 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002808}
2809
2810void Context::invalidateSubFramebuffer(GLenum target,
2811 GLsizei numAttachments,
2812 const GLenum *attachments,
2813 GLint x,
2814 GLint y,
2815 GLsizei width,
2816 GLsizei height)
2817{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002818 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002820
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002821 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002822 ASSERT(framebuffer);
2823
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002824 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002825 {
Jamie Madill437fa652016-05-03 15:13:24 -04002826 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002827 }
Jamie Madill437fa652016-05-03 15:13:24 -04002828
2829 Rectangle area(x, y, width, height);
2830 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002831}
2832
Jamie Madill73a84962016-02-12 09:27:23 -05002833void Context::texImage2D(GLenum target,
2834 GLint level,
2835 GLint internalformat,
2836 GLsizei width,
2837 GLsizei height,
2838 GLint border,
2839 GLenum format,
2840 GLenum type,
2841 const GLvoid *pixels)
2842{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002843 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002844
2845 Extents size(width, height, 1);
2846 Texture *texture =
2847 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002848 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002849 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002850}
2851
2852void Context::texImage3D(GLenum target,
2853 GLint level,
2854 GLint internalformat,
2855 GLsizei width,
2856 GLsizei height,
2857 GLsizei depth,
2858 GLint border,
2859 GLenum format,
2860 GLenum type,
2861 const GLvoid *pixels)
2862{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002863 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002864
2865 Extents size(width, height, depth);
2866 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002867 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002868 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002869}
2870
2871void Context::texSubImage2D(GLenum target,
2872 GLint level,
2873 GLint xoffset,
2874 GLint yoffset,
2875 GLsizei width,
2876 GLsizei height,
2877 GLenum format,
2878 GLenum type,
2879 const GLvoid *pixels)
2880{
2881 // Zero sized uploads are valid but no-ops
2882 if (width == 0 || height == 0)
2883 {
2884 return;
2885 }
2886
Jamie Madillad9f24e2016-02-12 09:27:24 -05002887 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002888
2889 Box area(xoffset, yoffset, 0, width, height, 1);
2890 Texture *texture =
2891 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002892 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002893 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002894}
2895
2896void Context::texSubImage3D(GLenum target,
2897 GLint level,
2898 GLint xoffset,
2899 GLint yoffset,
2900 GLint zoffset,
2901 GLsizei width,
2902 GLsizei height,
2903 GLsizei depth,
2904 GLenum format,
2905 GLenum type,
2906 const GLvoid *pixels)
2907{
2908 // Zero sized uploads are valid but no-ops
2909 if (width == 0 || height == 0 || depth == 0)
2910 {
2911 return;
2912 }
2913
Jamie Madillad9f24e2016-02-12 09:27:24 -05002914 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002915
2916 Box area(xoffset, yoffset, zoffset, width, height, depth);
2917 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002918 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002919 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002920}
2921
2922void Context::compressedTexImage2D(GLenum target,
2923 GLint level,
2924 GLenum internalformat,
2925 GLsizei width,
2926 GLsizei height,
2927 GLint border,
2928 GLsizei imageSize,
2929 const GLvoid *data)
2930{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002931 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002932
2933 Extents size(width, height, 1);
2934 Texture *texture =
2935 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002936 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2937 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002938 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002939}
2940
2941void Context::compressedTexImage3D(GLenum target,
2942 GLint level,
2943 GLenum internalformat,
2944 GLsizei width,
2945 GLsizei height,
2946 GLsizei depth,
2947 GLint border,
2948 GLsizei imageSize,
2949 const GLvoid *data)
2950{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002951 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002952
2953 Extents size(width, height, depth);
2954 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002955 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2956 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002957 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002958}
2959
2960void Context::compressedTexSubImage2D(GLenum target,
2961 GLint level,
2962 GLint xoffset,
2963 GLint yoffset,
2964 GLsizei width,
2965 GLsizei height,
2966 GLenum format,
2967 GLsizei imageSize,
2968 const GLvoid *data)
2969{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002970 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002971
2972 Box area(xoffset, yoffset, 0, width, height, 1);
2973 Texture *texture =
2974 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002975 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2976 format, imageSize,
2977 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002978}
2979
2980void Context::compressedTexSubImage3D(GLenum target,
2981 GLint level,
2982 GLint xoffset,
2983 GLint yoffset,
2984 GLint zoffset,
2985 GLsizei width,
2986 GLsizei height,
2987 GLsizei depth,
2988 GLenum format,
2989 GLsizei imageSize,
2990 const GLvoid *data)
2991{
2992 // Zero sized uploads are valid but no-ops
2993 if (width == 0 || height == 0)
2994 {
2995 return;
2996 }
2997
Jamie Madillad9f24e2016-02-12 09:27:24 -05002998 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002999
3000 Box area(xoffset, yoffset, zoffset, width, height, depth);
3001 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003002 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
3003 format, imageSize,
3004 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003005}
3006
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003007void Context::generateMipmap(GLenum target)
3008{
3009 Texture *texture = getTargetTexture(target);
3010 handleError(texture->generateMipmap());
3011}
3012
Geoff Langc287ea62016-09-16 14:46:51 -04003013GLboolean Context::enableExtension(const char *name)
3014{
3015 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
3016 ASSERT(extensionInfos.find(name) != extensionInfos.end());
3017 const auto &extension = extensionInfos.at(name);
3018 ASSERT(extension.Enableable);
3019
3020 if (mExtensions.*(extension.ExtensionsMember))
3021 {
3022 // Extension already enabled
3023 return GL_TRUE;
3024 }
3025
3026 const auto &nativeExtensions = mImplementation->getNativeExtensions();
3027 if (!(nativeExtensions.*(extension.ExtensionsMember)))
3028 {
3029 // Underlying implementation does not support this valid extension
3030 return GL_FALSE;
3031 }
3032
3033 mExtensions.*(extension.ExtensionsMember) = true;
3034 updateCaps();
3035 initExtensionStrings();
3036 return GL_TRUE;
3037}
3038
Geoff Lang97073d12016-04-20 10:42:34 -07003039void Context::copyTextureCHROMIUM(GLuint sourceId,
3040 GLuint destId,
3041 GLint internalFormat,
3042 GLenum destType,
3043 GLboolean unpackFlipY,
3044 GLboolean unpackPremultiplyAlpha,
3045 GLboolean unpackUnmultiplyAlpha)
3046{
3047 syncStateForTexImage();
3048
3049 gl::Texture *sourceTexture = getTexture(sourceId);
3050 gl::Texture *destTexture = getTexture(destId);
3051 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3052 unpackPremultiplyAlpha == GL_TRUE,
3053 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3054}
3055
3056void Context::copySubTextureCHROMIUM(GLuint sourceId,
3057 GLuint destId,
3058 GLint xoffset,
3059 GLint yoffset,
3060 GLint x,
3061 GLint y,
3062 GLsizei width,
3063 GLsizei height,
3064 GLboolean unpackFlipY,
3065 GLboolean unpackPremultiplyAlpha,
3066 GLboolean unpackUnmultiplyAlpha)
3067{
3068 // Zero sized copies are valid but no-ops
3069 if (width == 0 || height == 0)
3070 {
3071 return;
3072 }
3073
3074 syncStateForTexImage();
3075
3076 gl::Texture *sourceTexture = getTexture(sourceId);
3077 gl::Texture *destTexture = getTexture(destId);
3078 Offset offset(xoffset, yoffset, 0);
3079 Rectangle area(x, y, width, height);
3080 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3081 unpackPremultiplyAlpha == GL_TRUE,
3082 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3083}
3084
Geoff Lang47110bf2016-04-20 11:13:22 -07003085void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3086{
3087 syncStateForTexImage();
3088
3089 gl::Texture *sourceTexture = getTexture(sourceId);
3090 gl::Texture *destTexture = getTexture(destId);
3091 handleError(destTexture->copyCompressedTexture(sourceTexture));
3092}
3093
Olli Etuaho4f667482016-03-30 15:56:35 +03003094void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
3095{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003096 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003097 ASSERT(buffer);
3098
3099 if (!buffer->isMapped())
3100 {
3101 *params = nullptr;
3102 }
3103 else
3104 {
3105 *params = buffer->getMapPointer();
3106 }
3107}
3108
3109GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3110{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003111 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003112 ASSERT(buffer);
3113
3114 Error error = buffer->map(access);
3115 if (error.isError())
3116 {
Jamie Madill437fa652016-05-03 15:13:24 -04003117 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003118 return nullptr;
3119 }
3120
3121 return buffer->getMapPointer();
3122}
3123
3124GLboolean Context::unmapBuffer(GLenum target)
3125{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003126 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003127 ASSERT(buffer);
3128
3129 GLboolean result;
3130 Error error = buffer->unmap(&result);
3131 if (error.isError())
3132 {
Jamie Madill437fa652016-05-03 15:13:24 -04003133 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003134 return GL_FALSE;
3135 }
3136
3137 return result;
3138}
3139
3140GLvoid *Context::mapBufferRange(GLenum target,
3141 GLintptr offset,
3142 GLsizeiptr length,
3143 GLbitfield access)
3144{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003145 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003146 ASSERT(buffer);
3147
3148 Error error = buffer->mapRange(offset, length, access);
3149 if (error.isError())
3150 {
Jamie Madill437fa652016-05-03 15:13:24 -04003151 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003152 return nullptr;
3153 }
3154
3155 return buffer->getMapPointer();
3156}
3157
3158void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3159{
3160 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3161}
3162
Jamie Madillad9f24e2016-02-12 09:27:24 -05003163void Context::syncStateForReadPixels()
3164{
3165 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3166}
3167
3168void Context::syncStateForTexImage()
3169{
3170 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3171}
3172
3173void Context::syncStateForClear()
3174{
3175 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3176}
3177
3178void Context::syncStateForBlit()
3179{
3180 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3181}
3182
Jamie Madillc20ab272016-06-09 07:20:46 -07003183void Context::activeTexture(GLenum texture)
3184{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003185 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003186}
3187
3188void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3189{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003190 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003191}
3192
3193void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3194{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003195 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003196}
3197
3198void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3199{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003200 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003201}
3202
3203void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3204{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003205 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003206}
3207
3208void Context::clearDepthf(GLclampf depth)
3209{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003210 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003211}
3212
3213void Context::clearStencil(GLint s)
3214{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003215 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003216}
3217
3218void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3219{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003220 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003221}
3222
3223void Context::cullFace(GLenum mode)
3224{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003225 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003226}
3227
3228void Context::depthFunc(GLenum func)
3229{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003230 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003231}
3232
3233void Context::depthMask(GLboolean flag)
3234{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003235 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003236}
3237
3238void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3239{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003240 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003241}
3242
3243void Context::disable(GLenum cap)
3244{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003245 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003246}
3247
3248void Context::disableVertexAttribArray(GLuint index)
3249{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003250 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003251}
3252
3253void Context::enable(GLenum cap)
3254{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003255 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003256}
3257
3258void Context::enableVertexAttribArray(GLuint index)
3259{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003260 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003261}
3262
3263void Context::frontFace(GLenum mode)
3264{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003265 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003266}
3267
3268void Context::hint(GLenum target, GLenum mode)
3269{
3270 switch (target)
3271 {
3272 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003273 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003274 break;
3275
3276 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003277 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003278 break;
3279
3280 default:
3281 UNREACHABLE();
3282 return;
3283 }
3284}
3285
3286void Context::lineWidth(GLfloat width)
3287{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003288 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003289}
3290
3291void Context::pixelStorei(GLenum pname, GLint param)
3292{
3293 switch (pname)
3294 {
3295 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003297 break;
3298
3299 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003300 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003301 break;
3302
3303 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003304 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003305 break;
3306
3307 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003308 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003309 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003310 break;
3311
3312 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003313 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003314 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003315 break;
3316
3317 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003318 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003319 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003320 break;
3321
3322 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003323 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003324 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003325 break;
3326
3327 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003328 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003329 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003330 break;
3331
3332 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003333 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335 break;
3336
3337 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003338 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340 break;
3341
3342 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003343 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345 break;
3346
3347 default:
3348 UNREACHABLE();
3349 return;
3350 }
3351}
3352
3353void Context::polygonOffset(GLfloat factor, GLfloat units)
3354{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003355 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003356}
3357
3358void Context::sampleCoverage(GLclampf value, GLboolean invert)
3359{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003360 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003361}
3362
3363void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3364{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003365 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003366}
3367
3368void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3369{
3370 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3371 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003372 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003373 }
3374
3375 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3376 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003377 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003378 }
3379}
3380
3381void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3382{
3383 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3384 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003385 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003386 }
3387
3388 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3389 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003390 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003391 }
3392}
3393
3394void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3395{
3396 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3397 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003398 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003399 }
3400
3401 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3402 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003403 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003404 }
3405}
3406
3407void Context::vertexAttrib1f(GLuint index, GLfloat x)
3408{
3409 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003410 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003411}
3412
3413void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3414{
3415 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003416 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003417}
3418
3419void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3420{
3421 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003422 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003423}
3424
3425void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3426{
3427 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003428 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003429}
3430
3431void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3432{
3433 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003434 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003435}
3436
3437void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3438{
3439 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003440 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003441}
3442
3443void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3444{
3445 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003446 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003447}
3448
3449void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3450{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003451 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003452}
3453
3454void Context::vertexAttribPointer(GLuint index,
3455 GLint size,
3456 GLenum type,
3457 GLboolean normalized,
3458 GLsizei stride,
3459 const GLvoid *ptr)
3460{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003461 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3462 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003463}
3464
3465void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3466{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003467 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003468}
3469
3470void Context::vertexAttribIPointer(GLuint index,
3471 GLint size,
3472 GLenum type,
3473 GLsizei stride,
3474 const GLvoid *pointer)
3475{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003476 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3477 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003478}
3479
3480void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3481{
3482 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484}
3485
3486void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3487{
3488 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003489 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003490}
3491
3492void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3493{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003494 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003495}
3496
3497void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3498{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003499 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003500}
3501
3502void Context::debugMessageControl(GLenum source,
3503 GLenum type,
3504 GLenum severity,
3505 GLsizei count,
3506 const GLuint *ids,
3507 GLboolean enabled)
3508{
3509 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3511 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003512}
3513
3514void Context::debugMessageInsert(GLenum source,
3515 GLenum type,
3516 GLuint id,
3517 GLenum severity,
3518 GLsizei length,
3519 const GLchar *buf)
3520{
3521 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003522 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003523}
3524
3525void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3526{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003527 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003528}
3529
3530GLuint Context::getDebugMessageLog(GLuint count,
3531 GLsizei bufSize,
3532 GLenum *sources,
3533 GLenum *types,
3534 GLuint *ids,
3535 GLenum *severities,
3536 GLsizei *lengths,
3537 GLchar *messageLog)
3538{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003539 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3540 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003541}
3542
3543void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3544{
3545 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003546 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003547}
3548
3549void Context::popDebugGroup()
3550{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003551 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003552}
3553
Jamie Madill29639852016-09-02 15:00:09 -04003554void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3555{
3556 Buffer *buffer = mGLState.getTargetBuffer(target);
3557 ASSERT(buffer);
3558 handleError(buffer->bufferData(target, data, size, usage));
3559}
3560
3561void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3562{
3563 if (data == nullptr)
3564 {
3565 return;
3566 }
3567
3568 Buffer *buffer = mGLState.getTargetBuffer(target);
3569 ASSERT(buffer);
3570 handleError(buffer->bufferSubData(target, data, size, offset));
3571}
3572
Jamie Madillef300b12016-10-07 15:12:09 -04003573void Context::attachShader(GLuint program, GLuint shader)
3574{
3575 auto programObject = mResourceManager->getProgram(program);
3576 auto shaderObject = mResourceManager->getShader(shader);
3577 ASSERT(programObject && shaderObject);
3578 programObject->attachShader(shaderObject);
3579}
3580
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003581const Workarounds &Context::getWorkarounds() const
3582{
3583 return mWorkarounds;
3584}
3585
Jamie Madillc29968b2016-01-20 11:17:23 -05003586} // namespace gl