blob: 83cee978d6ec9dc62c4ee88b7f3e056b7abe8ac2 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050021#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050022#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050029#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/ResourceManager.h"
31#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050032#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050033#include "libANGLE/Texture.h"
34#include "libANGLE/TransformFeedback.h"
35#include "libANGLE/VertexArray.h"
36#include "libANGLE/formatutils.h"
37#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070038#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040039#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040040#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030041#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040042#include "libANGLE/queryutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000043
Geoff Langf6db0982015-08-25 13:04:00 -040044namespace
45{
46
Ian Ewell3ffd78b2016-01-22 16:09:42 -050047template <typename T>
Sami Väisänend59ca052016-06-21 16:10:00 +030048std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
49 GLsizei numPaths,
50 const void *paths,
51 GLuint pathBase)
52{
53 std::vector<gl::Path *> ret;
54 ret.reserve(numPaths);
55
56 const auto *nameArray = static_cast<const T *>(paths);
57
58 for (GLsizei i = 0; i < numPaths; ++i)
59 {
60 const GLuint pathName = nameArray[i] + pathBase;
61
62 ret.push_back(resourceManager.getPath(pathName));
63 }
64
65 return ret;
66}
67
68std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
69 GLsizei numPaths,
70 GLenum pathNameType,
71 const void *paths,
72 GLuint pathBase)
73{
74 switch (pathNameType)
75 {
76 case GL_UNSIGNED_BYTE:
77 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
78
79 case GL_BYTE:
80 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
81
82 case GL_UNSIGNED_SHORT:
83 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_SHORT:
86 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_INT:
89 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_INT:
92 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
93 }
94
95 UNREACHABLE();
96 return std::vector<gl::Path *>();
97}
98
99template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400100gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500101{
Geoff Lang2186c382016-10-14 10:54:54 -0400102 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500103
104 switch (pname)
105 {
106 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400107 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500108 case GL_QUERY_RESULT_AVAILABLE_EXT:
109 {
110 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400111 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500112 if (!error.isError())
113 {
Geoff Lang2186c382016-10-14 10:54:54 -0400114 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500115 }
116 return error;
117 }
118 default:
119 UNREACHABLE();
120 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
121 }
122}
123
Geoff Langf6db0982015-08-25 13:04:00 -0400124void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
125{
Geoff Lang1a683462015-09-29 15:09:59 -0400126 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400127 {
128 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
129 tfBufferIndex++)
130 {
131 const OffsetBindingPointer<gl::Buffer> &buffer =
132 transformFeedback->getIndexedBuffer(tfBufferIndex);
133 if (buffer.get() != nullptr)
134 {
135 buffer->onTransformFeedback();
136 }
137 }
138 }
139}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140
141// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300142EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500143{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400144 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500145}
146
Martin Radev1be913c2016-07-11 17:59:16 +0300147EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
148{
149 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
150}
151
Geoff Langeb66a6e2016-10-31 13:06:12 -0400152gl::Version GetClientVersion(const egl::AttributeMap &attribs)
153{
154 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
155}
156
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500157GLenum GetResetStrategy(const egl::AttributeMap &attribs)
158{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400159 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
160 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500161 switch (attrib)
162 {
163 case EGL_NO_RESET_NOTIFICATION:
164 return GL_NO_RESET_NOTIFICATION_EXT;
165 case EGL_LOSE_CONTEXT_ON_RESET:
166 return GL_LOSE_CONTEXT_ON_RESET_EXT;
167 default:
168 UNREACHABLE();
169 return GL_NONE;
170 }
171}
172
173bool GetRobustAccess(const egl::AttributeMap &attribs)
174{
Geoff Lang077f20a2016-11-01 10:08:02 -0400175 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
176 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
177 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500178}
179
180bool GetDebug(const egl::AttributeMap &attribs)
181{
Geoff Lang077f20a2016-11-01 10:08:02 -0400182 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
183 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184}
185
186bool GetNoError(const egl::AttributeMap &attribs)
187{
188 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
189}
190
Geoff Langc287ea62016-09-16 14:46:51 -0400191bool GetWebGLContext(const egl::AttributeMap &attribs)
192{
193 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
194}
195
Geoff Langf41a7152016-09-19 15:11:17 -0400196bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
197{
198 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
199}
200
Martin Radev9d901792016-07-15 15:58:58 +0300201std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
202{
203 std::string labelName;
204 if (label != nullptr)
205 {
206 size_t labelLength = length < 0 ? strlen(label) : length;
207 labelName = std::string(label, labelLength);
208 }
209 return labelName;
210}
211
212void GetObjectLabelBase(const std::string &objectLabel,
213 GLsizei bufSize,
214 GLsizei *length,
215 GLchar *label)
216{
217 size_t writeLength = objectLabel.length();
218 if (label != nullptr && bufSize > 0)
219 {
220 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
221 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
222 label[writeLength] = '\0';
223 }
224
225 if (length != nullptr)
226 {
227 *length = static_cast<GLsizei>(writeLength);
228 }
229}
230
Geoff Langf6db0982015-08-25 13:04:00 -0400231} // anonymous namespace
232
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000233namespace gl
234{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000235
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400236Context::Context(rx::EGLImplFactory *implFactory,
237 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400238 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500239 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300240
Geoff Langeb66a6e2016-10-31 13:06:12 -0400241 : ValidationContext(GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700242 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500243 mCaps,
244 mTextureCaps,
245 mExtensions,
246 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500247 mLimitations,
248 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700249 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500250 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400251 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500252 mClientType(EGL_OPENGL_ES_API),
253 mHasBeenCurrent(false),
254 mContextLost(false),
255 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700256 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500257 mResetStrategy(GetResetStrategy(attribs)),
258 mRobustAccess(GetRobustAccess(attribs)),
259 mCurrentSurface(nullptr),
260 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000261{
Geoff Lang077f20a2016-11-01 10:08:02 -0400262 if (mRobustAccess)
263 {
264 UNIMPLEMENTED();
265 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000266
Geoff Langc287ea62016-09-16 14:46:51 -0400267 initCaps(GetWebGLContext(attribs));
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700268 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400269
Geoff Langeb66a6e2016-10-31 13:06:12 -0400270 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400271 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100272
Shannon Woods53a94a82014-06-24 15:20:36 -0400273 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400274
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400275 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276 {
277 mResourceManager = shareContext->mResourceManager;
278 mResourceManager->addRef();
279 }
280 else
281 {
Jamie Madill901b3792016-05-26 09:20:40 -0400282 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000283 }
284
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700285 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400286
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000287 // [OpenGL ES 2.0.24] section 3.7 page 83:
288 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
289 // and cube map texture state vectors respectively associated with them.
290 // In order that access to these initial textures not be lost, they are treated as texture
291 // objects all of whose names are 0.
292
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400293 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500294 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400296 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500297 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400298
Geoff Langeb66a6e2016-10-31 13:06:12 -0400299 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400300 {
301 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400302 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500303 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400304
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400305 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500306 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400307 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000308
Ian Ewellbda75592016-04-18 17:25:54 -0400309 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
310 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400311 Texture *zeroTextureExternal =
312 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400313 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
314 }
315
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700316 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500317
Jamie Madill57a89722013-07-02 11:57:03 -0400318 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000319 bindArrayBuffer(0);
320 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400321
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000322 bindRenderbuffer(0);
323
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000324 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400325 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000326 {
327 bindIndexedUniformBuffer(0, i, 0, -1);
328 }
329
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000330 bindCopyReadBuffer(0);
331 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000332 bindPixelPackBuffer(0);
333 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000334
Geoff Langeb66a6e2016-10-31 13:06:12 -0400335 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400336 {
337 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
338 // In the initial state, a default transform feedback object is bound and treated as
339 // a transform feedback object with a name of zero. That object is bound any time
340 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400341 bindTransformFeedback(0);
342 }
Geoff Langc8058452014-02-03 12:04:11 -0500343
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700344 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500345
346 // Initialize dirty bit masks
347 // TODO(jmadill): additional ES3 state
348 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
349 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
350 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
351 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
352 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
353 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400354 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500355 // No dirty objects.
356
357 // Readpixels uses the pack state and read FBO
358 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
359 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
360 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
361 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
362 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400363 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500364 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
365
366 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
367 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
368 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
369 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
370 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
371 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
372 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
373 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
374 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
375 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
376 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
377 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
378
379 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
380 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700381 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500382 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
383 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400384
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400385 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000386}
387
388Context::~Context()
389{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700390 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000391
Corentin Wallez37c39792015-08-20 14:19:46 -0400392 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000393 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400394 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400395 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400396 {
397 SafeDelete(framebuffer.second);
398 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000399 }
400
Corentin Wallez80b24112015-08-25 16:41:57 -0400401 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000402 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400403 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000404 }
405
Corentin Wallez80b24112015-08-25 16:41:57 -0400406 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400408 if (query.second != nullptr)
409 {
410 query.second->release();
411 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000412 }
413
Corentin Wallez80b24112015-08-25 16:41:57 -0400414 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400415 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400416 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400417 }
418
Corentin Wallez80b24112015-08-25 16:41:57 -0400419 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500420 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500421 if (transformFeedback.second != nullptr)
422 {
423 transformFeedback.second->release();
424 }
Geoff Langc8058452014-02-03 12:04:11 -0500425 }
426
Jamie Madilldedd7b92014-11-05 16:30:36 -0500427 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400428 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500429 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400430 }
431 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000432
Corentin Wallez51706ea2015-08-07 14:39:22 -0400433 if (mCurrentSurface != nullptr)
434 {
435 releaseSurface();
436 }
437
Jamie Madill1e9ae072014-11-06 15:27:21 -0500438 if (mResourceManager)
439 {
440 mResourceManager->release();
441 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500442
443 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000444}
445
daniel@transgaming.comad629872012-11-28 19:32:06 +0000446void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000447{
Jamie Madill77a72f62015-04-14 11:18:32 -0400448 ASSERT(surface != nullptr);
449
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000450 if (!mHasBeenCurrent)
451 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000452 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400453 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000454
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700455 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
456 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000457
458 mHasBeenCurrent = true;
459 }
460
Jamie Madill1b94d432015-08-07 13:23:23 -0400461 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700462 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400463
Corentin Wallez51706ea2015-08-07 14:39:22 -0400464 if (mCurrentSurface)
465 {
466 releaseSurface();
467 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000468 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400469 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000470
Corentin Wallez37c39792015-08-20 14:19:46 -0400471 // Update default framebuffer, the binding of the previous default
472 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400473 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400474 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700475 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400476 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700477 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400478 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700479 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400480 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700481 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400482 }
483 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400484 }
Ian Ewell292f0052016-02-04 10:37:32 -0500485
486 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700487 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488}
489
Jamie Madill77a72f62015-04-14 11:18:32 -0400490void Context::releaseSurface()
491{
Corentin Wallez37c39792015-08-20 14:19:46 -0400492 ASSERT(mCurrentSurface != nullptr);
493
494 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400495 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400496 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700497 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400498 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700499 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400500 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700501 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400502 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700503 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400504 }
505 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400506 }
507
Corentin Wallez51706ea2015-08-07 14:39:22 -0400508 mCurrentSurface->setIsCurrent(false);
509 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400510}
511
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000512GLuint Context::createBuffer()
513{
514 return mResourceManager->createBuffer();
515}
516
517GLuint Context::createProgram()
518{
Jamie Madill901b3792016-05-26 09:20:40 -0400519 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000520}
521
522GLuint Context::createShader(GLenum type)
523{
Jamie Madill901b3792016-05-26 09:20:40 -0400524 return mResourceManager->createShader(mImplementation.get(),
525 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000526}
527
528GLuint Context::createTexture()
529{
530 return mResourceManager->createTexture();
531}
532
533GLuint Context::createRenderbuffer()
534{
535 return mResourceManager->createRenderbuffer();
536}
537
Geoff Lang882033e2014-09-30 11:26:07 -0400538GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400539{
Jamie Madill901b3792016-05-26 09:20:40 -0400540 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400541
Cooper Partind8e62a32015-01-29 15:21:25 -0800542 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400543}
544
Sami Väisänene45e53b2016-05-25 10:36:04 +0300545GLuint Context::createPaths(GLsizei range)
546{
547 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
548 if (resultOrError.isError())
549 {
550 handleError(resultOrError.getError());
551 return 0;
552 }
553 return resultOrError.getResult();
554}
555
Jamie Madill57a89722013-07-02 11:57:03 -0400556GLuint Context::createVertexArray()
557{
Geoff Lang36167ab2015-12-07 10:27:14 -0500558 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
559 mVertexArrayMap[vertexArray] = nullptr;
560 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400561}
562
Jamie Madilldc356042013-07-19 16:36:57 -0400563GLuint Context::createSampler()
564{
565 return mResourceManager->createSampler();
566}
567
Geoff Langc8058452014-02-03 12:04:11 -0500568GLuint Context::createTransformFeedback()
569{
Geoff Lang36167ab2015-12-07 10:27:14 -0500570 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
571 mTransformFeedbackMap[transformFeedback] = nullptr;
572 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500573}
574
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000575// Returns an unused framebuffer name
576GLuint Context::createFramebuffer()
577{
578 GLuint handle = mFramebufferHandleAllocator.allocate();
579
580 mFramebufferMap[handle] = NULL;
581
582 return handle;
583}
584
Jamie Madill33dc8432013-07-26 11:55:05 -0400585GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000586{
Jamie Madill33dc8432013-07-26 11:55:05 -0400587 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000588
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400589 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000590
591 return handle;
592}
593
594// Returns an unused query name
595GLuint Context::createQuery()
596{
597 GLuint handle = mQueryHandleAllocator.allocate();
598
599 mQueryMap[handle] = NULL;
600
601 return handle;
602}
603
604void Context::deleteBuffer(GLuint buffer)
605{
606 if (mResourceManager->getBuffer(buffer))
607 {
608 detachBuffer(buffer);
609 }
Jamie Madill893ab082014-05-16 16:56:10 -0400610
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000611 mResourceManager->deleteBuffer(buffer);
612}
613
614void Context::deleteShader(GLuint shader)
615{
616 mResourceManager->deleteShader(shader);
617}
618
619void Context::deleteProgram(GLuint program)
620{
621 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622}
623
624void Context::deleteTexture(GLuint texture)
625{
626 if (mResourceManager->getTexture(texture))
627 {
628 detachTexture(texture);
629 }
630
631 mResourceManager->deleteTexture(texture);
632}
633
634void Context::deleteRenderbuffer(GLuint renderbuffer)
635{
636 if (mResourceManager->getRenderbuffer(renderbuffer))
637 {
638 detachRenderbuffer(renderbuffer);
639 }
Jamie Madill893ab082014-05-16 16:56:10 -0400640
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641 mResourceManager->deleteRenderbuffer(renderbuffer);
642}
643
Jamie Madillcd055f82013-07-26 11:55:15 -0400644void Context::deleteFenceSync(GLsync fenceSync)
645{
646 // The spec specifies the underlying Fence object is not deleted until all current
647 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
648 // and since our API is currently designed for being called from a single thread, we can delete
649 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700650 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400651}
652
Sami Väisänene45e53b2016-05-25 10:36:04 +0300653void Context::deletePaths(GLuint first, GLsizei range)
654{
655 mResourceManager->deletePaths(first, range);
656}
657
658bool Context::hasPathData(GLuint path) const
659{
660 const auto *pathObj = mResourceManager->getPath(path);
661 if (pathObj == nullptr)
662 return false;
663
664 return pathObj->hasPathData();
665}
666
667bool Context::hasPath(GLuint path) const
668{
669 return mResourceManager->hasPath(path);
670}
671
672void Context::setPathCommands(GLuint path,
673 GLsizei numCommands,
674 const GLubyte *commands,
675 GLsizei numCoords,
676 GLenum coordType,
677 const void *coords)
678{
679 auto *pathObject = mResourceManager->getPath(path);
680
681 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
682}
683
684void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
685{
686 auto *pathObj = mResourceManager->getPath(path);
687
688 switch (pname)
689 {
690 case GL_PATH_STROKE_WIDTH_CHROMIUM:
691 pathObj->setStrokeWidth(value);
692 break;
693 case GL_PATH_END_CAPS_CHROMIUM:
694 pathObj->setEndCaps(static_cast<GLenum>(value));
695 break;
696 case GL_PATH_JOIN_STYLE_CHROMIUM:
697 pathObj->setJoinStyle(static_cast<GLenum>(value));
698 break;
699 case GL_PATH_MITER_LIMIT_CHROMIUM:
700 pathObj->setMiterLimit(value);
701 break;
702 case GL_PATH_STROKE_BOUND_CHROMIUM:
703 pathObj->setStrokeBound(value);
704 break;
705 default:
706 UNREACHABLE();
707 break;
708 }
709}
710
711void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
712{
713 const auto *pathObj = mResourceManager->getPath(path);
714
715 switch (pname)
716 {
717 case GL_PATH_STROKE_WIDTH_CHROMIUM:
718 *value = pathObj->getStrokeWidth();
719 break;
720 case GL_PATH_END_CAPS_CHROMIUM:
721 *value = static_cast<GLfloat>(pathObj->getEndCaps());
722 break;
723 case GL_PATH_JOIN_STYLE_CHROMIUM:
724 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
725 break;
726 case GL_PATH_MITER_LIMIT_CHROMIUM:
727 *value = pathObj->getMiterLimit();
728 break;
729 case GL_PATH_STROKE_BOUND_CHROMIUM:
730 *value = pathObj->getStrokeBound();
731 break;
732 default:
733 UNREACHABLE();
734 break;
735 }
736}
737
738void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
739{
740 mGLState.setPathStencilFunc(func, ref, mask);
741}
742
Jamie Madill57a89722013-07-02 11:57:03 -0400743void Context::deleteVertexArray(GLuint vertexArray)
744{
Geoff Lang36167ab2015-12-07 10:27:14 -0500745 auto iter = mVertexArrayMap.find(vertexArray);
746 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000747 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500748 VertexArray *vertexArrayObject = iter->second;
749 if (vertexArrayObject != nullptr)
750 {
751 detachVertexArray(vertexArray);
752 delete vertexArrayObject;
753 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000754
Geoff Lang36167ab2015-12-07 10:27:14 -0500755 mVertexArrayMap.erase(iter);
756 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400757 }
758}
759
Jamie Madilldc356042013-07-19 16:36:57 -0400760void Context::deleteSampler(GLuint sampler)
761{
762 if (mResourceManager->getSampler(sampler))
763 {
764 detachSampler(sampler);
765 }
766
767 mResourceManager->deleteSampler(sampler);
768}
769
Geoff Langc8058452014-02-03 12:04:11 -0500770void Context::deleteTransformFeedback(GLuint transformFeedback)
771{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500772 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500773 if (iter != mTransformFeedbackMap.end())
774 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500775 TransformFeedback *transformFeedbackObject = iter->second;
776 if (transformFeedbackObject != nullptr)
777 {
778 detachTransformFeedback(transformFeedback);
779 transformFeedbackObject->release();
780 }
781
Geoff Lang50b3fe82015-12-08 14:49:12 +0000782 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500783 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500784 }
785}
786
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000787void Context::deleteFramebuffer(GLuint framebuffer)
788{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500789 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000790
791 if (framebufferObject != mFramebufferMap.end())
792 {
793 detachFramebuffer(framebuffer);
794
795 mFramebufferHandleAllocator.release(framebufferObject->first);
796 delete framebufferObject->second;
797 mFramebufferMap.erase(framebufferObject);
798 }
799}
800
Jamie Madill33dc8432013-07-26 11:55:05 -0400801void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000802{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500803 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000804
Jamie Madill33dc8432013-07-26 11:55:05 -0400805 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000806 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400807 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000808 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400809 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810 }
811}
812
813void Context::deleteQuery(GLuint query)
814{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500815 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816 if (queryObject != mQueryMap.end())
817 {
818 mQueryHandleAllocator.release(queryObject->first);
819 if (queryObject->second)
820 {
821 queryObject->second->release();
822 }
823 mQueryMap.erase(queryObject);
824 }
825}
826
Geoff Lang70d0f492015-12-10 17:45:46 -0500827Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000828{
829 return mResourceManager->getBuffer(handle);
830}
831
Jamie Madill570f7c82014-07-03 10:38:54 -0400832Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000833{
834 return mResourceManager->getTexture(handle);
835}
836
Geoff Lang70d0f492015-12-10 17:45:46 -0500837Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000838{
839 return mResourceManager->getRenderbuffer(handle);
840}
841
Jamie Madillcd055f82013-07-26 11:55:15 -0400842FenceSync *Context::getFenceSync(GLsync handle) const
843{
Minmin Gong794e0002015-04-07 18:31:54 -0700844 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400845}
846
Jamie Madill57a89722013-07-02 11:57:03 -0400847VertexArray *Context::getVertexArray(GLuint handle) const
848{
849 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500850 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400851}
852
Jamie Madilldc356042013-07-19 16:36:57 -0400853Sampler *Context::getSampler(GLuint handle) const
854{
855 return mResourceManager->getSampler(handle);
856}
857
Geoff Langc8058452014-02-03 12:04:11 -0500858TransformFeedback *Context::getTransformFeedback(GLuint handle) const
859{
Geoff Lang36167ab2015-12-07 10:27:14 -0500860 auto iter = mTransformFeedbackMap.find(handle);
861 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500862}
863
Geoff Lang70d0f492015-12-10 17:45:46 -0500864LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
865{
866 switch (identifier)
867 {
868 case GL_BUFFER:
869 return getBuffer(name);
870 case GL_SHADER:
871 return getShader(name);
872 case GL_PROGRAM:
873 return getProgram(name);
874 case GL_VERTEX_ARRAY:
875 return getVertexArray(name);
876 case GL_QUERY:
877 return getQuery(name);
878 case GL_TRANSFORM_FEEDBACK:
879 return getTransformFeedback(name);
880 case GL_SAMPLER:
881 return getSampler(name);
882 case GL_TEXTURE:
883 return getTexture(name);
884 case GL_RENDERBUFFER:
885 return getRenderbuffer(name);
886 case GL_FRAMEBUFFER:
887 return getFramebuffer(name);
888 default:
889 UNREACHABLE();
890 return nullptr;
891 }
892}
893
894LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
895{
896 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
897}
898
Martin Radev9d901792016-07-15 15:58:58 +0300899void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
900{
901 LabeledObject *object = getLabeledObject(identifier, name);
902 ASSERT(object != nullptr);
903
904 std::string labelName = GetObjectLabelFromPointer(length, label);
905 object->setLabel(labelName);
906}
907
908void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
909{
910 LabeledObject *object = getLabeledObjectFromPtr(ptr);
911 ASSERT(object != nullptr);
912
913 std::string labelName = GetObjectLabelFromPointer(length, label);
914 object->setLabel(labelName);
915}
916
917void Context::getObjectLabel(GLenum identifier,
918 GLuint name,
919 GLsizei bufSize,
920 GLsizei *length,
921 GLchar *label) const
922{
923 LabeledObject *object = getLabeledObject(identifier, name);
924 ASSERT(object != nullptr);
925
926 const std::string &objectLabel = object->getLabel();
927 GetObjectLabelBase(objectLabel, bufSize, length, label);
928}
929
930void Context::getObjectPtrLabel(const void *ptr,
931 GLsizei bufSize,
932 GLsizei *length,
933 GLchar *label) const
934{
935 LabeledObject *object = getLabeledObjectFromPtr(ptr);
936 ASSERT(object != nullptr);
937
938 const std::string &objectLabel = object->getLabel();
939 GetObjectLabelBase(objectLabel, bufSize, length, label);
940}
941
Jamie Madilldc356042013-07-19 16:36:57 -0400942bool Context::isSampler(GLuint samplerName) const
943{
944 return mResourceManager->isSampler(samplerName);
945}
946
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500947void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948{
Jamie Madill901b3792016-05-26 09:20:40 -0400949 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700950 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000951}
952
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500953void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954{
Jamie Madill901b3792016-05-26 09:20:40 -0400955 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700956 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000957}
958
Jamie Madilldedd7b92014-11-05 16:30:36 -0500959void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000960{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500961 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000962
Jamie Madilldedd7b92014-11-05 16:30:36 -0500963 if (handle == 0)
964 {
965 texture = mZeroTextures[target].get();
966 }
967 else
968 {
Jamie Madill901b3792016-05-26 09:20:40 -0400969 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500970 }
971
972 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700973 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000974}
975
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500976void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500978 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700979 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980}
981
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500982void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000983{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500984 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700985 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000986}
987
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500988void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989{
Jamie Madill901b3792016-05-26 09:20:40 -0400990 Renderbuffer *renderbuffer =
991 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700992 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993}
994
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500995void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400996{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500997 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700998 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400999}
1000
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001001void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001002{
Geoff Lang76b10c92014-09-05 16:28:14 -04001003 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001004 Sampler *sampler =
1005 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001006 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001007}
1008
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001009void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001010{
Jamie Madill901b3792016-05-26 09:20:40 -04001011 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001012 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001013}
1014
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001015void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1016 GLuint index,
1017 GLintptr offset,
1018 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001019{
Jamie Madill901b3792016-05-26 09:20:40 -04001020 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001022}
1023
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001025{
Jamie Madill901b3792016-05-26 09:20:40 -04001026 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001028}
1029
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001030void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1031 GLuint index,
1032 GLintptr offset,
1033 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001034{
Jamie Madill901b3792016-05-26 09:20:40 -04001035 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001036 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001037}
1038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001040{
Jamie Madill901b3792016-05-26 09:20:40 -04001041 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001042 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001043}
1044
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001045void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001046{
Jamie Madill901b3792016-05-26 09:20:40 -04001047 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001048 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001049}
1050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001051void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001052{
Jamie Madill901b3792016-05-26 09:20:40 -04001053 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001054 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001055}
1056
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001057void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001058{
Jamie Madill901b3792016-05-26 09:20:40 -04001059 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001060 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001061}
1062
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001063void Context::useProgram(GLuint program)
1064{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001065 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001066}
1067
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001068void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001069{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001070 TransformFeedback *transformFeedback =
1071 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001072 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001073}
1074
Geoff Lang5aad9672014-09-08 11:10:42 -04001075Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001078 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001079
Geoff Lang5aad9672014-09-08 11:10:42 -04001080 // begin query
1081 Error error = queryObject->begin();
1082 if (error.isError())
1083 {
1084 return error;
1085 }
1086
1087 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001088 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001089
Geoff Lang5aad9672014-09-08 11:10:42 -04001090 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091}
1092
Geoff Lang5aad9672014-09-08 11:10:42 -04001093Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001094{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001095 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001096 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001097
Geoff Lang5aad9672014-09-08 11:10:42 -04001098 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001099
Geoff Lang5aad9672014-09-08 11:10:42 -04001100 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001101 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001102
1103 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001104}
1105
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001106Error Context::queryCounter(GLuint id, GLenum target)
1107{
1108 ASSERT(target == GL_TIMESTAMP_EXT);
1109
1110 Query *queryObject = getQuery(id, true, target);
1111 ASSERT(queryObject);
1112
1113 return queryObject->queryCounter();
1114}
1115
1116void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1117{
1118 switch (pname)
1119 {
1120 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001121 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001122 break;
1123 case GL_QUERY_COUNTER_BITS_EXT:
1124 switch (target)
1125 {
1126 case GL_TIME_ELAPSED_EXT:
1127 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1128 break;
1129 case GL_TIMESTAMP_EXT:
1130 params[0] = getExtensions().queryCounterBitsTimestamp;
1131 break;
1132 default:
1133 UNREACHABLE();
1134 params[0] = 0;
1135 break;
1136 }
1137 break;
1138 default:
1139 UNREACHABLE();
1140 return;
1141 }
1142}
1143
Geoff Lang2186c382016-10-14 10:54:54 -04001144void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001145{
Geoff Lang2186c382016-10-14 10:54:54 -04001146 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001147}
1148
Geoff Lang2186c382016-10-14 10:54:54 -04001149void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001150{
Geoff Lang2186c382016-10-14 10:54:54 -04001151 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001152}
1153
Geoff Lang2186c382016-10-14 10:54:54 -04001154void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001155{
Geoff Lang2186c382016-10-14 10:54:54 -04001156 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001157}
1158
Geoff Lang2186c382016-10-14 10:54:54 -04001159void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001160{
Geoff Lang2186c382016-10-14 10:54:54 -04001161 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001162}
1163
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001164Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001166 auto framebufferIt = mFramebufferMap.find(handle);
1167 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001168}
1169
Jamie Madill33dc8432013-07-26 11:55:05 -04001170FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001172 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173
Jamie Madill33dc8432013-07-26 11:55:05 -04001174 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175 {
1176 return NULL;
1177 }
1178 else
1179 {
1180 return fence->second;
1181 }
1182}
1183
1184Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1185{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001186 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187
1188 if (query == mQueryMap.end())
1189 {
1190 return NULL;
1191 }
1192 else
1193 {
1194 if (!query->second && create)
1195 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001196 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197 query->second->addRef();
1198 }
1199 return query->second;
1200 }
1201}
1202
Geoff Lang70d0f492015-12-10 17:45:46 -05001203Query *Context::getQuery(GLuint handle) const
1204{
1205 auto iter = mQueryMap.find(handle);
1206 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1207}
1208
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001209Texture *Context::getTargetTexture(GLenum target) const
1210{
Ian Ewellbda75592016-04-18 17:25:54 -04001211 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001212 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001213}
1214
Geoff Lang76b10c92014-09-05 16:28:14 -04001215Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001217 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218}
1219
Geoff Lang492a7e42014-11-05 13:27:06 -05001220Compiler *Context::getCompiler() const
1221{
1222 return mCompiler;
1223}
1224
Jamie Madill893ab082014-05-16 16:56:10 -04001225void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226{
1227 switch (pname)
1228 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001229 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001230 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001231 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001232 mGLState.getBooleanv(pname, params);
1233 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001234 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235}
1236
Jamie Madill893ab082014-05-16 16:56:10 -04001237void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238{
Shannon Woods53a94a82014-06-24 15:20:36 -04001239 // Queries about context capabilities and maximums are answered by Context.
1240 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241 switch (pname)
1242 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001244 params[0] = mCaps.minAliasedLineWidth;
1245 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246 break;
1247 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001248 params[0] = mCaps.minAliasedPointSize;
1249 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001251 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001252 ASSERT(mExtensions.textureFilterAnisotropic);
1253 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001254 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001255 case GL_MAX_TEXTURE_LOD_BIAS:
1256 *params = mCaps.maxLODBias;
1257 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001258
1259 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1260 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1261 {
1262 ASSERT(mExtensions.pathRendering);
1263 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1264 memcpy(params, m, 16 * sizeof(GLfloat));
1265 }
1266 break;
1267
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001269 mGLState.getFloatv(pname, params);
1270 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272}
1273
Jamie Madill893ab082014-05-16 16:56:10 -04001274void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275{
Shannon Woods53a94a82014-06-24 15:20:36 -04001276 // Queries about context capabilities and maximums are answered by Context.
1277 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001278
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279 switch (pname)
1280 {
Geoff Lang301d1612014-07-09 10:34:37 -04001281 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1282 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1283 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001284 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1285 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1286 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001287 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1288 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1289 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001290 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001291 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1292 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1293 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001294 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001295 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001296 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1297 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1298 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1299 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001300 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1301 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001302 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1303 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001304 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001305 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1306 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1307 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1308 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001309 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001310 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001311 break;
1312 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001313 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001314 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001315 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1316 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001317 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1318 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1319 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001320 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1321 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1322 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001323 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324 case GL_MAX_VIEWPORT_DIMS:
1325 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001326 params[0] = mCaps.maxViewportWidth;
1327 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 }
1329 break;
1330 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001331 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001333 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1334 *params = mResetStrategy;
1335 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001336 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001337 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001338 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001339 case GL_SHADER_BINARY_FORMATS:
1340 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1341 break;
1342 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001343 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001344 break;
1345 case GL_PROGRAM_BINARY_FORMATS:
1346 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001347 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001348 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001349 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001350 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001351
1352 // GL_KHR_debug
1353 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1354 *params = mExtensions.maxDebugMessageLength;
1355 break;
1356 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1357 *params = mExtensions.maxDebugLoggedMessages;
1358 break;
1359 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1360 *params = mExtensions.maxDebugGroupStackDepth;
1361 break;
1362 case GL_MAX_LABEL_LENGTH:
1363 *params = mExtensions.maxLabelLength;
1364 break;
1365
Ian Ewell53f59f42016-01-28 17:36:55 -05001366 // GL_EXT_disjoint_timer_query
1367 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001368 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001369 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001370 case GL_MAX_FRAMEBUFFER_WIDTH:
1371 *params = mCaps.maxFramebufferWidth;
1372 break;
1373 case GL_MAX_FRAMEBUFFER_HEIGHT:
1374 *params = mCaps.maxFramebufferHeight;
1375 break;
1376 case GL_MAX_FRAMEBUFFER_SAMPLES:
1377 *params = mCaps.maxFramebufferSamples;
1378 break;
1379 case GL_MAX_SAMPLE_MASK_WORDS:
1380 *params = mCaps.maxSampleMaskWords;
1381 break;
1382 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1383 *params = mCaps.maxColorTextureSamples;
1384 break;
1385 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1386 *params = mCaps.maxDepthTextureSamples;
1387 break;
1388 case GL_MAX_INTEGER_SAMPLES:
1389 *params = mCaps.maxIntegerSamples;
1390 break;
1391 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1392 *params = mCaps.maxVertexAttribRelativeOffset;
1393 break;
1394 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1395 *params = mCaps.maxVertexAttribBindings;
1396 break;
1397 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1398 *params = mCaps.maxVertexAttribStride;
1399 break;
1400 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1401 *params = mCaps.maxVertexAtomicCounterBuffers;
1402 break;
1403 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1404 *params = mCaps.maxVertexAtomicCounters;
1405 break;
1406 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1407 *params = mCaps.maxVertexImageUniforms;
1408 break;
1409 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1410 *params = mCaps.maxVertexShaderStorageBlocks;
1411 break;
1412 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1413 *params = mCaps.maxFragmentAtomicCounterBuffers;
1414 break;
1415 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1416 *params = mCaps.maxFragmentAtomicCounters;
1417 break;
1418 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1419 *params = mCaps.maxFragmentImageUniforms;
1420 break;
1421 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1422 *params = mCaps.maxFragmentShaderStorageBlocks;
1423 break;
1424 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1425 *params = mCaps.minProgramTextureGatherOffset;
1426 break;
1427 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1428 *params = mCaps.maxProgramTextureGatherOffset;
1429 break;
1430 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1431 *params = mCaps.maxComputeWorkGroupInvocations;
1432 break;
1433 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1434 *params = mCaps.maxComputeUniformBlocks;
1435 break;
1436 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1437 *params = mCaps.maxComputeTextureImageUnits;
1438 break;
1439 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1440 *params = mCaps.maxComputeSharedMemorySize;
1441 break;
1442 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1443 *params = mCaps.maxComputeUniformComponents;
1444 break;
1445 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1446 *params = mCaps.maxComputeAtomicCounterBuffers;
1447 break;
1448 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1449 *params = mCaps.maxComputeAtomicCounters;
1450 break;
1451 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1452 *params = mCaps.maxComputeImageUniforms;
1453 break;
1454 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1455 *params = mCaps.maxCombinedComputeUniformComponents;
1456 break;
1457 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1458 *params = mCaps.maxComputeShaderStorageBlocks;
1459 break;
1460 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1461 *params = mCaps.maxCombinedShaderOutputResources;
1462 break;
1463 case GL_MAX_UNIFORM_LOCATIONS:
1464 *params = mCaps.maxUniformLocations;
1465 break;
1466 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1467 *params = mCaps.maxAtomicCounterBufferBindings;
1468 break;
1469 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1470 *params = mCaps.maxAtomicCounterBufferSize;
1471 break;
1472 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1473 *params = mCaps.maxCombinedAtomicCounterBuffers;
1474 break;
1475 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1476 *params = mCaps.maxCombinedAtomicCounters;
1477 break;
1478 case GL_MAX_IMAGE_UNITS:
1479 *params = mCaps.maxImageUnits;
1480 break;
1481 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1482 *params = mCaps.maxCombinedImageUniforms;
1483 break;
1484 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1485 *params = mCaps.maxShaderStorageBufferBindings;
1486 break;
1487 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1488 *params = mCaps.maxCombinedShaderStorageBlocks;
1489 break;
1490 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1491 *params = mCaps.shaderStorageBufferOffsetAlignment;
1492 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001493 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001494 mGLState.getIntegerv(mState, pname, params);
1495 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001496 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001497}
1498
Jamie Madill893ab082014-05-16 16:56:10 -04001499void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001500{
Shannon Woods53a94a82014-06-24 15:20:36 -04001501 // Queries about context capabilities and maximums are answered by Context.
1502 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001503 switch (pname)
1504 {
1505 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001506 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001507 break;
1508 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001509 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001510 break;
1511 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001512 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001513 break;
1514 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001515 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001516 break;
1517 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001518 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001519 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001520
1521 // GL_EXT_disjoint_timer_query
1522 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001523 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001524 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001525
1526 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1527 *params = mCaps.maxShaderStorageBlockSize;
1528 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001529 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001530 UNREACHABLE();
1531 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001532 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001533}
1534
Geoff Lang70d0f492015-12-10 17:45:46 -05001535void Context::getPointerv(GLenum pname, void **params) const
1536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001537 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001538}
1539
Martin Radev66fb8202016-07-28 11:45:20 +03001540void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001541{
Shannon Woods53a94a82014-06-24 15:20:36 -04001542 // Queries about context capabilities and maximums are answered by Context.
1543 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001544
1545 GLenum nativeType;
1546 unsigned int numParams;
1547 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1548 ASSERT(queryStatus);
1549
1550 if (nativeType == GL_INT)
1551 {
1552 switch (target)
1553 {
1554 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1555 ASSERT(index < 3u);
1556 *data = mCaps.maxComputeWorkGroupCount[index];
1557 break;
1558 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1559 ASSERT(index < 3u);
1560 *data = mCaps.maxComputeWorkGroupSize[index];
1561 break;
1562 default:
1563 mGLState.getIntegeri_v(target, index, data);
1564 }
1565 }
1566 else
1567 {
1568 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1569 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001570}
1571
Martin Radev66fb8202016-07-28 11:45:20 +03001572void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001573{
Shannon Woods53a94a82014-06-24 15:20:36 -04001574 // Queries about context capabilities and maximums are answered by Context.
1575 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001576
1577 GLenum nativeType;
1578 unsigned int numParams;
1579 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1580 ASSERT(queryStatus);
1581
1582 if (nativeType == GL_INT_64_ANGLEX)
1583 {
1584 mGLState.getInteger64i_v(target, index, data);
1585 }
1586 else
1587 {
1588 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1589 }
1590}
1591
1592void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1593{
1594 // Queries about context capabilities and maximums are answered by Context.
1595 // Queries about current GL state values are answered by State.
1596
1597 GLenum nativeType;
1598 unsigned int numParams;
1599 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1600 ASSERT(queryStatus);
1601
1602 if (nativeType == GL_BOOL)
1603 {
1604 mGLState.getBooleani_v(target, index, data);
1605 }
1606 else
1607 {
1608 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1609 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001610}
1611
Geoff Langf6db0982015-08-25 13:04:00 -04001612Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001613{
Jamie Madill1b94d432015-08-07 13:23:23 -04001614 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001615 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001616 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001617
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001618 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001619}
1620
Geoff Langf6db0982015-08-25 13:04:00 -04001621Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1622{
1623 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001624 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001625 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001626
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001627 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001628}
1629
1630Error Context::drawElements(GLenum mode,
1631 GLsizei count,
1632 GLenum type,
1633 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001634 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001635{
Jamie Madill1b94d432015-08-07 13:23:23 -04001636 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001637 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001638}
1639
1640Error Context::drawElementsInstanced(GLenum mode,
1641 GLsizei count,
1642 GLenum type,
1643 const GLvoid *indices,
1644 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001645 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001646{
1647 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001648 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1649 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001650}
1651
1652Error Context::drawRangeElements(GLenum mode,
1653 GLuint start,
1654 GLuint end,
1655 GLsizei count,
1656 GLenum type,
1657 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001658 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001659{
1660 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001661 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001662}
1663
Geoff Lang129753a2015-01-09 16:52:09 -05001664Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001665{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001666 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001667}
1668
1669Error Context::finish()
1670{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001671 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001672}
1673
Austin Kinross6ee1e782015-05-29 17:05:37 -07001674void Context::insertEventMarker(GLsizei length, const char *marker)
1675{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001676 ASSERT(mImplementation);
1677 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001678}
1679
1680void Context::pushGroupMarker(GLsizei length, const char *marker)
1681{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001682 ASSERT(mImplementation);
1683 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001684}
1685
1686void Context::popGroupMarker()
1687{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001688 ASSERT(mImplementation);
1689 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001690}
1691
Geoff Langd8605522016-04-13 10:19:12 -04001692void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1693{
1694 Program *programObject = getProgram(program);
1695 ASSERT(programObject);
1696
1697 programObject->bindUniformLocation(location, name);
1698}
1699
Sami Väisänena797e062016-05-12 15:23:40 +03001700void Context::setCoverageModulation(GLenum components)
1701{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001702 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001703}
1704
Sami Väisänene45e53b2016-05-25 10:36:04 +03001705void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1706{
1707 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1708}
1709
1710void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1711{
1712 GLfloat I[16];
1713 angle::Matrix<GLfloat>::setToIdentity(I);
1714
1715 mGLState.loadPathRenderingMatrix(matrixMode, I);
1716}
1717
1718void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1719{
1720 const auto *pathObj = mResourceManager->getPath(path);
1721 if (!pathObj)
1722 return;
1723
1724 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1725 syncRendererState();
1726
1727 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1728}
1729
1730void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1731{
1732 const auto *pathObj = mResourceManager->getPath(path);
1733 if (!pathObj)
1734 return;
1735
1736 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1737 syncRendererState();
1738
1739 mImplementation->stencilStrokePath(pathObj, reference, mask);
1740}
1741
1742void Context::coverFillPath(GLuint path, GLenum coverMode)
1743{
1744 const auto *pathObj = mResourceManager->getPath(path);
1745 if (!pathObj)
1746 return;
1747
1748 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1749 syncRendererState();
1750
1751 mImplementation->coverFillPath(pathObj, coverMode);
1752}
1753
1754void Context::coverStrokePath(GLuint path, GLenum coverMode)
1755{
1756 const auto *pathObj = mResourceManager->getPath(path);
1757 if (!pathObj)
1758 return;
1759
1760 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1761 syncRendererState();
1762
1763 mImplementation->coverStrokePath(pathObj, coverMode);
1764}
1765
1766void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1767{
1768 const auto *pathObj = mResourceManager->getPath(path);
1769 if (!pathObj)
1770 return;
1771
1772 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1773 syncRendererState();
1774
1775 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1776}
1777
1778void Context::stencilThenCoverStrokePath(GLuint path,
1779 GLint reference,
1780 GLuint mask,
1781 GLenum coverMode)
1782{
1783 const auto *pathObj = mResourceManager->getPath(path);
1784 if (!pathObj)
1785 return;
1786
1787 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1788 syncRendererState();
1789
1790 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1791}
1792
Sami Väisänend59ca052016-06-21 16:10:00 +03001793void Context::coverFillPathInstanced(GLsizei numPaths,
1794 GLenum pathNameType,
1795 const void *paths,
1796 GLuint pathBase,
1797 GLenum coverMode,
1798 GLenum transformType,
1799 const GLfloat *transformValues)
1800{
1801 const auto &pathObjects =
1802 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1803
1804 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1805 syncRendererState();
1806
1807 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1808}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001809
Sami Väisänend59ca052016-06-21 16:10:00 +03001810void Context::coverStrokePathInstanced(GLsizei numPaths,
1811 GLenum pathNameType,
1812 const void *paths,
1813 GLuint pathBase,
1814 GLenum coverMode,
1815 GLenum transformType,
1816 const GLfloat *transformValues)
1817{
1818 const auto &pathObjects =
1819 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1820
1821 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1822 syncRendererState();
1823
1824 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1825 transformValues);
1826}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001827
Sami Väisänend59ca052016-06-21 16:10:00 +03001828void Context::stencilFillPathInstanced(GLsizei numPaths,
1829 GLenum pathNameType,
1830 const void *paths,
1831 GLuint pathBase,
1832 GLenum fillMode,
1833 GLuint mask,
1834 GLenum transformType,
1835 const GLfloat *transformValues)
1836{
1837 const auto &pathObjects =
1838 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1839
1840 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1841 syncRendererState();
1842
1843 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1844 transformValues);
1845}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001846
Sami Väisänend59ca052016-06-21 16:10:00 +03001847void Context::stencilStrokePathInstanced(GLsizei numPaths,
1848 GLenum pathNameType,
1849 const void *paths,
1850 GLuint pathBase,
1851 GLint reference,
1852 GLuint mask,
1853 GLenum transformType,
1854 const GLfloat *transformValues)
1855{
1856 const auto &pathObjects =
1857 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1858
1859 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1860 syncRendererState();
1861
1862 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1863 transformValues);
1864}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001865
Sami Väisänend59ca052016-06-21 16:10:00 +03001866void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1867 GLenum pathNameType,
1868 const void *paths,
1869 GLuint pathBase,
1870 GLenum fillMode,
1871 GLuint mask,
1872 GLenum coverMode,
1873 GLenum transformType,
1874 const GLfloat *transformValues)
1875{
1876 const auto &pathObjects =
1877 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1878
1879 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1880 syncRendererState();
1881
1882 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1883 transformType, transformValues);
1884}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001885
Sami Väisänend59ca052016-06-21 16:10:00 +03001886void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1887 GLenum pathNameType,
1888 const void *paths,
1889 GLuint pathBase,
1890 GLint reference,
1891 GLuint mask,
1892 GLenum coverMode,
1893 GLenum transformType,
1894 const GLfloat *transformValues)
1895{
1896 const auto &pathObjects =
1897 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1898
1899 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1900 syncRendererState();
1901
1902 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1903 transformType, transformValues);
1904}
1905
Sami Väisänen46eaa942016-06-29 10:26:37 +03001906void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1907{
1908 auto *programObject = getProgram(program);
1909
1910 programObject->bindFragmentInputLocation(location, name);
1911}
1912
1913void Context::programPathFragmentInputGen(GLuint program,
1914 GLint location,
1915 GLenum genMode,
1916 GLint components,
1917 const GLfloat *coeffs)
1918{
1919 auto *programObject = getProgram(program);
1920
1921 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1922}
1923
Jamie Madill437fa652016-05-03 15:13:24 -04001924void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001925{
Geoff Langda5777c2014-07-11 09:52:58 -04001926 if (error.isError())
1927 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001928 GLenum code = error.getCode();
1929 mErrors.insert(code);
1930 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1931 {
1932 markContextLost();
1933 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001934
1935 if (!error.getMessage().empty())
1936 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001937 auto *debug = &mGLState.getDebug();
1938 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1939 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001940 }
Geoff Langda5777c2014-07-11 09:52:58 -04001941 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001942}
1943
1944// Get one of the recorded errors and clear its flag, if any.
1945// [OpenGL ES 2.0.24] section 2.5 page 13.
1946GLenum Context::getError()
1947{
Geoff Langda5777c2014-07-11 09:52:58 -04001948 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001949 {
Geoff Langda5777c2014-07-11 09:52:58 -04001950 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001951 }
Geoff Langda5777c2014-07-11 09:52:58 -04001952 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001953 {
Geoff Langda5777c2014-07-11 09:52:58 -04001954 GLenum error = *mErrors.begin();
1955 mErrors.erase(mErrors.begin());
1956 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001957 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001958}
1959
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001960// NOTE: this function should not assume that this context is current!
1961void Context::markContextLost()
1962{
1963 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001964 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001965 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001966 mContextLostForced = true;
1967 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001968 mContextLost = true;
1969}
1970
1971bool Context::isContextLost()
1972{
1973 return mContextLost;
1974}
1975
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001976GLenum Context::getResetStatus()
1977{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001978 // Even if the application doesn't want to know about resets, we want to know
1979 // as it will allow us to skip all the calls.
1980 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001981 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001982 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001983 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001984 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001985 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001986
1987 // EXT_robustness, section 2.6: If the reset notification behavior is
1988 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1989 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1990 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001991 }
1992
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001993 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1994 // status should be returned at least once, and GL_NO_ERROR should be returned
1995 // once the device has finished resetting.
1996 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001997 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001998 ASSERT(mResetStatus == GL_NO_ERROR);
1999 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002000
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002001 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002002 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002003 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002004 }
2005 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002006 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002007 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002008 // If markContextLost was used to mark the context lost then
2009 // assume that is not recoverable, and continue to report the
2010 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002011 mResetStatus = mImplementation->getResetStatus();
2012 }
Jamie Madill893ab082014-05-16 16:56:10 -04002013
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002014 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002015}
2016
2017bool Context::isResetNotificationEnabled()
2018{
2019 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2020}
2021
Corentin Walleze3b10e82015-05-20 11:06:25 -04002022const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002023{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002024 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002025}
2026
2027EGLenum Context::getClientType() const
2028{
2029 return mClientType;
2030}
2031
2032EGLenum Context::getRenderBuffer() const
2033{
Corentin Wallez37c39792015-08-20 14:19:46 -04002034 auto framebufferIt = mFramebufferMap.find(0);
2035 if (framebufferIt != mFramebufferMap.end())
2036 {
2037 const Framebuffer *framebuffer = framebufferIt->second;
2038 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2039
2040 ASSERT(backAttachment != nullptr);
2041 return backAttachment->getSurface()->getRenderBuffer();
2042 }
2043 else
2044 {
2045 return EGL_NONE;
2046 }
Régis Fénéon83107972015-02-05 12:57:44 +01002047}
2048
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002049VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002050{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002051 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002052 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2053 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002054 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002055 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2056
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002057 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002058 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002059
2060 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002061}
2062
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002063TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002064{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002065 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002066 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2067 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002068 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002069 transformFeedback =
2070 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002071 transformFeedback->addRef();
2072 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002073 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002074
2075 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002076}
2077
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002078Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2079{
2080 // Can be called from Bind without a prior call to Gen.
2081 auto framebufferIt = mFramebufferMap.find(framebuffer);
2082 bool neverCreated = framebufferIt == mFramebufferMap.end();
2083 if (neverCreated || framebufferIt->second == nullptr)
2084 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002085 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002086 if (neverCreated)
2087 {
2088 mFramebufferHandleAllocator.reserve(framebuffer);
2089 mFramebufferMap[framebuffer] = newFBO;
2090 return newFBO;
2091 }
2092
2093 framebufferIt->second = newFBO;
2094 }
2095
2096 return framebufferIt->second;
2097}
2098
Geoff Langf41a7152016-09-19 15:11:17 -04002099bool Context::isTextureGenerated(GLuint texture) const
2100{
2101 return mResourceManager->isTextureGenerated(texture);
2102}
2103
2104bool Context::isBufferGenerated(GLuint buffer) const
2105{
2106 return mResourceManager->isBufferGenerated(buffer);
2107}
2108
2109bool Context::isRenderbufferGenerated(GLuint renderbuffer) const
2110{
2111 return mResourceManager->isRenderbufferGenerated(renderbuffer);
2112}
2113
2114bool Context::isFramebufferGenerated(GLuint framebuffer) const
2115{
2116 ASSERT(mFramebufferMap.find(0) != mFramebufferMap.end());
2117 return mFramebufferMap.find(framebuffer) != mFramebufferMap.end();
2118}
2119
Geoff Lang36167ab2015-12-07 10:27:14 -05002120bool Context::isVertexArrayGenerated(GLuint vertexArray)
2121{
Geoff Langf41a7152016-09-19 15:11:17 -04002122 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002123 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2124}
2125
2126bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2127{
Geoff Langf41a7152016-09-19 15:11:17 -04002128 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002129 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2130}
2131
Shannon Woods53a94a82014-06-24 15:20:36 -04002132void Context::detachTexture(GLuint texture)
2133{
2134 // Simple pass-through to State's detachTexture method, as textures do not require
2135 // allocation map management either here or in the resource manager at detach time.
2136 // Zero textures are held by the Context, and we don't attempt to request them from
2137 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002138 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002139}
2140
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002141void Context::detachBuffer(GLuint buffer)
2142{
Yuly Novikov5807a532015-12-03 13:01:22 -05002143 // Simple pass-through to State's detachBuffer method, since
2144 // only buffer attachments to container objects that are bound to the current context
2145 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002146
Yuly Novikov5807a532015-12-03 13:01:22 -05002147 // [OpenGL ES 3.2] section 5.1.2 page 45:
2148 // Attachments to unbound container objects, such as
2149 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2150 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002151 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002152}
2153
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002154void Context::detachFramebuffer(GLuint framebuffer)
2155{
Shannon Woods53a94a82014-06-24 15:20:36 -04002156 // Framebuffer detachment is handled by Context, because 0 is a valid
2157 // Framebuffer object, and a pointer to it must be passed from Context
2158 // to State at binding time.
2159
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002160 // [OpenGL ES 2.0.24] section 4.4 page 107:
2161 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2162 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2163
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002164 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002165 {
2166 bindReadFramebuffer(0);
2167 }
2168
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002169 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002170 {
2171 bindDrawFramebuffer(0);
2172 }
2173}
2174
2175void Context::detachRenderbuffer(GLuint renderbuffer)
2176{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002177 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002178}
2179
Jamie Madill57a89722013-07-02 11:57:03 -04002180void Context::detachVertexArray(GLuint vertexArray)
2181{
Jamie Madill77a72f62015-04-14 11:18:32 -04002182 // Vertex array detachment is handled by Context, because 0 is a valid
2183 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002184 // binding time.
2185
Jamie Madill57a89722013-07-02 11:57:03 -04002186 // [OpenGL ES 3.0.2] section 2.10 page 43:
2187 // If a vertex array object that is currently bound is deleted, the binding
2188 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002189 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002190 {
2191 bindVertexArray(0);
2192 }
2193}
2194
Geoff Langc8058452014-02-03 12:04:11 -05002195void Context::detachTransformFeedback(GLuint transformFeedback)
2196{
Corentin Walleza2257da2016-04-19 16:43:12 -04002197 // Transform feedback detachment is handled by Context, because 0 is a valid
2198 // transform feedback, and a pointer to it must be passed from Context to State at
2199 // binding time.
2200
2201 // The OpenGL specification doesn't mention what should happen when the currently bound
2202 // transform feedback object is deleted. Since it is a container object, we treat it like
2203 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002204 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002205 {
2206 bindTransformFeedback(0);
2207 }
Geoff Langc8058452014-02-03 12:04:11 -05002208}
2209
Jamie Madilldc356042013-07-19 16:36:57 -04002210void Context::detachSampler(GLuint sampler)
2211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002212 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002213}
2214
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002215void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002217 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002218}
2219
Jamie Madille29d1672013-07-19 16:36:57 -04002220void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2221{
Geoff Langc1984ed2016-10-07 12:41:00 -04002222 Sampler *samplerObject =
2223 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2224 SetSamplerParameteri(samplerObject, pname, param);
2225}
Jamie Madille29d1672013-07-19 16:36:57 -04002226
Geoff Langc1984ed2016-10-07 12:41:00 -04002227void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2228{
2229 Sampler *samplerObject =
2230 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2231 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002232}
2233
2234void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2235{
Geoff Langc1984ed2016-10-07 12:41:00 -04002236 Sampler *samplerObject =
2237 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2238 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002239}
2240
Geoff Langc1984ed2016-10-07 12:41:00 -04002241void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002242{
Geoff Langc1984ed2016-10-07 12:41:00 -04002243 Sampler *samplerObject =
2244 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2245 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002246}
2247
Geoff Langc1984ed2016-10-07 12:41:00 -04002248void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002249{
Geoff Langc1984ed2016-10-07 12:41:00 -04002250 const Sampler *samplerObject =
2251 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2252 QuerySamplerParameteriv(samplerObject, pname, params);
2253}
Jamie Madill9675b802013-07-19 16:36:59 -04002254
Geoff Langc1984ed2016-10-07 12:41:00 -04002255void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2256{
2257 const Sampler *samplerObject =
2258 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2259 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002260}
2261
Olli Etuahof0fee072016-03-30 15:11:58 +03002262void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2263{
2264 gl::Program *programObject = getProgram(program);
2265 ASSERT(programObject != nullptr);
2266
2267 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2268 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2269}
2270
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002271void Context::initRendererString()
2272{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002273 std::ostringstream rendererString;
2274 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002275 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002276 rendererString << ")";
2277
Geoff Langcec35902014-04-16 10:52:36 -04002278 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002279}
2280
Geoff Langc287ea62016-09-16 14:46:51 -04002281const char *Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002282{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002283 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002284}
2285
Geoff Langcec35902014-04-16 10:52:36 -04002286void Context::initExtensionStrings()
2287{
Geoff Langc287ea62016-09-16 14:46:51 -04002288 for (const auto &extensionString : mExtensions.getStrings())
2289 {
2290 mExtensionStrings.push_back(MakeStaticString(extensionString));
2291 }
Geoff Langcec35902014-04-16 10:52:36 -04002292
Geoff Langc0b9ef42014-07-02 10:02:37 -04002293 std::ostringstream combinedStringStream;
Geoff Langc287ea62016-09-16 14:46:51 -04002294 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(),
2295 std::ostream_iterator<const char *>(combinedStringStream, " "));
2296 mExtensionString = MakeStaticString(combinedStringStream.str());
Geoff Langcec35902014-04-16 10:52:36 -04002297}
2298
Geoff Langc287ea62016-09-16 14:46:51 -04002299const char *Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002300{
2301 return mExtensionString;
2302}
2303
Geoff Langc287ea62016-09-16 14:46:51 -04002304const char *Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002305{
2306 return mExtensionStrings[idx];
2307}
2308
2309size_t Context::getExtensionStringCount() const
2310{
2311 return mExtensionStrings.size();
2312}
2313
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002314void Context::beginTransformFeedback(GLenum primitiveMode)
2315{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002316 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002317 ASSERT(transformFeedback != nullptr);
2318 ASSERT(!transformFeedback->isPaused());
2319
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002320 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002321}
2322
2323bool Context::hasActiveTransformFeedback(GLuint program) const
2324{
2325 for (auto pair : mTransformFeedbackMap)
2326 {
2327 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2328 {
2329 return true;
2330 }
2331 }
2332 return false;
2333}
2334
Geoff Langc287ea62016-09-16 14:46:51 -04002335void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002336{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002337 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002338
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002339 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002340
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002341 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002342
Geoff Langeb66a6e2016-10-31 13:06:12 -04002343 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002344 {
2345 // Disable ES3+ extensions
2346 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002347 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002348 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002349 }
2350
Geoff Langeb66a6e2016-10-31 13:06:12 -04002351 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002352 {
2353 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2354 //mExtensions.sRGB = false;
2355 }
2356
Jamie Madill00ed7a12016-05-19 13:13:38 -04002357 // Some extensions are always available because they are implemented in the GL layer.
2358 mExtensions.bindUniformLocation = true;
2359 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002360 mExtensions.bindGeneratesResource = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002361
2362 // Enable the no error extension if the context was created with the flag.
2363 mExtensions.noError = mSkipValidation;
2364
Geoff Lang70d0f492015-12-10 17:45:46 -05002365 // Explicitly enable GL_KHR_debug
2366 mExtensions.debug = true;
2367 mExtensions.maxDebugMessageLength = 1024;
2368 mExtensions.maxDebugLoggedMessages = 1024;
2369 mExtensions.maxDebugGroupStackDepth = 1024;
2370 mExtensions.maxLabelLength = 1024;
2371
Geoff Langff5b2d52016-09-07 11:32:23 -04002372 // Explicitly enable GL_ANGLE_robust_client_memory
2373 mExtensions.robustClientMemory = true;
2374
Geoff Lang301d1612014-07-09 10:34:37 -04002375 // Apply implementation limits
2376 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002377 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2378 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2379
2380 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002381
Geoff Langc287ea62016-09-16 14:46:51 -04002382 // WebGL compatibility
2383 mExtensions.webglCompatibility = webGLContext;
2384 for (const auto &extensionInfo : GetExtensionInfoMap())
2385 {
2386 // If this context is for WebGL, disable all enableable extensions
2387 if (webGLContext && extensionInfo.second.Enableable)
2388 {
2389 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2390 }
2391 }
2392
2393 // Generate texture caps
2394 updateCaps();
2395}
2396
2397void Context::updateCaps()
2398{
Geoff Lang900013c2014-07-07 11:32:19 -04002399 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002400 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002401
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002402 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002403 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2404 {
2405 GLenum format = i->first;
2406 TextureCaps formatCaps = i->second;
2407
Geoff Lang5d601382014-07-22 15:14:06 -04002408 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002409
Geoff Lang0d8b7242015-09-09 14:56:53 -04002410 // Update the format caps based on the client version and extensions.
2411 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2412 // ES3.
2413 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002414 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002415 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002416 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002417 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002418 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002419
2420 // OpenGL ES does not support multisampling with integer formats
2421 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002422 {
Geoff Langd87878e2014-09-19 15:42:59 -04002423 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002424 }
Geoff Langd87878e2014-09-19 15:42:59 -04002425
2426 if (formatCaps.texturable && formatInfo.compressed)
2427 {
2428 mCaps.compressedTextureFormats.push_back(format);
2429 }
2430
2431 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002432 }
2433}
2434
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002435void Context::initWorkarounds()
2436{
2437 // Lose the context upon out of memory error if the application is
2438 // expecting to watch for those events.
2439 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2440}
2441
Jamie Madill1b94d432015-08-07 13:23:23 -04002442void Context::syncRendererState()
2443{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002444 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2445 mImplementation->syncState(mGLState, dirtyBits);
2446 mGLState.clearDirtyBits();
2447 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002448}
2449
Jamie Madillad9f24e2016-02-12 09:27:24 -05002450void Context::syncRendererState(const State::DirtyBits &bitMask,
2451 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002452{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002453 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2454 mImplementation->syncState(mGLState, dirtyBits);
2455 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002456
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002457 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002458}
Jamie Madillc29968b2016-01-20 11:17:23 -05002459
2460void Context::blitFramebuffer(GLint srcX0,
2461 GLint srcY0,
2462 GLint srcX1,
2463 GLint srcY1,
2464 GLint dstX0,
2465 GLint dstY0,
2466 GLint dstX1,
2467 GLint dstY1,
2468 GLbitfield mask,
2469 GLenum filter)
2470{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002471 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002472 ASSERT(drawFramebuffer);
2473
2474 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2475 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2476
Jamie Madillad9f24e2016-02-12 09:27:24 -05002477 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002478
Jamie Madill8415b5f2016-04-26 13:41:39 -04002479 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002480}
Jamie Madillc29968b2016-01-20 11:17:23 -05002481
2482void Context::clear(GLbitfield mask)
2483{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002484 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002485 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002486}
2487
2488void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2489{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002490 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002491 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2492 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002493}
2494
2495void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2496{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002497 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002498 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2499 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002500}
2501
2502void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2503{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002504 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002505 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2506 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002507}
2508
2509void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2510{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002511 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002512 ASSERT(framebufferObject);
2513
2514 // If a buffer is not present, the clear has no effect
2515 if (framebufferObject->getDepthbuffer() == nullptr &&
2516 framebufferObject->getStencilbuffer() == nullptr)
2517 {
2518 return;
2519 }
2520
Jamie Madillad9f24e2016-02-12 09:27:24 -05002521 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002522 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2523 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002524}
2525
2526void Context::readPixels(GLint x,
2527 GLint y,
2528 GLsizei width,
2529 GLsizei height,
2530 GLenum format,
2531 GLenum type,
2532 GLvoid *pixels)
2533{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002534 if (width == 0 || height == 0)
2535 {
2536 return;
2537 }
2538
Jamie Madillad9f24e2016-02-12 09:27:24 -05002539 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002540
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002541 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002542 ASSERT(framebufferObject);
2543
2544 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002545 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002546}
2547
2548void Context::copyTexImage2D(GLenum target,
2549 GLint level,
2550 GLenum internalformat,
2551 GLint x,
2552 GLint y,
2553 GLsizei width,
2554 GLsizei height,
2555 GLint border)
2556{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002557 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002558 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002559
Jamie Madillc29968b2016-01-20 11:17:23 -05002560 Rectangle sourceArea(x, y, width, height);
2561
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002562 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002563 Texture *texture =
2564 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002565 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002566}
2567
2568void Context::copyTexSubImage2D(GLenum target,
2569 GLint level,
2570 GLint xoffset,
2571 GLint yoffset,
2572 GLint x,
2573 GLint y,
2574 GLsizei width,
2575 GLsizei height)
2576{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002577 if (width == 0 || height == 0)
2578 {
2579 return;
2580 }
2581
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002582 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002583 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002584
Jamie Madillc29968b2016-01-20 11:17:23 -05002585 Offset destOffset(xoffset, yoffset, 0);
2586 Rectangle sourceArea(x, y, width, height);
2587
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002588 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002589 Texture *texture =
2590 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002591 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002592}
2593
2594void Context::copyTexSubImage3D(GLenum target,
2595 GLint level,
2596 GLint xoffset,
2597 GLint yoffset,
2598 GLint zoffset,
2599 GLint x,
2600 GLint y,
2601 GLsizei width,
2602 GLsizei height)
2603{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002604 if (width == 0 || height == 0)
2605 {
2606 return;
2607 }
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 Offset destOffset(xoffset, yoffset, zoffset);
2613 Rectangle sourceArea(x, y, width, height);
2614
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002615 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002616 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002617 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002618}
2619
2620void Context::framebufferTexture2D(GLenum target,
2621 GLenum attachment,
2622 GLenum textarget,
2623 GLuint texture,
2624 GLint level)
2625{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002626 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002627 ASSERT(framebuffer);
2628
2629 if (texture != 0)
2630 {
2631 Texture *textureObj = getTexture(texture);
2632
2633 ImageIndex index = ImageIndex::MakeInvalid();
2634
2635 if (textarget == GL_TEXTURE_2D)
2636 {
2637 index = ImageIndex::Make2D(level);
2638 }
2639 else
2640 {
2641 ASSERT(IsCubeMapTextureTarget(textarget));
2642 index = ImageIndex::MakeCube(textarget, level);
2643 }
2644
2645 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2646 }
2647 else
2648 {
2649 framebuffer->resetAttachment(attachment);
2650 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002651
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002652 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002653}
2654
2655void Context::framebufferRenderbuffer(GLenum target,
2656 GLenum attachment,
2657 GLenum renderbuffertarget,
2658 GLuint renderbuffer)
2659{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002660 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002661 ASSERT(framebuffer);
2662
2663 if (renderbuffer != 0)
2664 {
2665 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2666 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2667 renderbufferObject);
2668 }
2669 else
2670 {
2671 framebuffer->resetAttachment(attachment);
2672 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002673
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002674 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002675}
2676
2677void Context::framebufferTextureLayer(GLenum target,
2678 GLenum attachment,
2679 GLuint texture,
2680 GLint level,
2681 GLint layer)
2682{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002683 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002684 ASSERT(framebuffer);
2685
2686 if (texture != 0)
2687 {
2688 Texture *textureObject = getTexture(texture);
2689
2690 ImageIndex index = ImageIndex::MakeInvalid();
2691
2692 if (textureObject->getTarget() == GL_TEXTURE_3D)
2693 {
2694 index = ImageIndex::Make3D(level, layer);
2695 }
2696 else
2697 {
2698 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2699 index = ImageIndex::Make2DArray(level, layer);
2700 }
2701
2702 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2703 }
2704 else
2705 {
2706 framebuffer->resetAttachment(attachment);
2707 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002708
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002709 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002710}
2711
2712void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2713{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002714 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002715 ASSERT(framebuffer);
2716 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002717 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002718}
2719
2720void Context::readBuffer(GLenum mode)
2721{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002722 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002723 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002724 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002725}
2726
2727void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2728{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002729 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002730 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002731
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002732 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002733 ASSERT(framebuffer);
2734
2735 // The specification isn't clear what should be done when the framebuffer isn't complete.
2736 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002737 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002738}
2739
2740void Context::invalidateFramebuffer(GLenum target,
2741 GLsizei numAttachments,
2742 const GLenum *attachments)
2743{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002744 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002745 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002746
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002747 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002748 ASSERT(framebuffer);
2749
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002750 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002751 {
Jamie Madill437fa652016-05-03 15:13:24 -04002752 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002753 }
Jamie Madill437fa652016-05-03 15:13:24 -04002754
2755 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002756}
2757
2758void Context::invalidateSubFramebuffer(GLenum target,
2759 GLsizei numAttachments,
2760 const GLenum *attachments,
2761 GLint x,
2762 GLint y,
2763 GLsizei width,
2764 GLsizei height)
2765{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002766 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002767 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002768
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002769 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002770 ASSERT(framebuffer);
2771
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002772 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002773 {
Jamie Madill437fa652016-05-03 15:13:24 -04002774 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002775 }
Jamie Madill437fa652016-05-03 15:13:24 -04002776
2777 Rectangle area(x, y, width, height);
2778 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002779}
2780
Jamie Madill73a84962016-02-12 09:27:23 -05002781void Context::texImage2D(GLenum target,
2782 GLint level,
2783 GLint internalformat,
2784 GLsizei width,
2785 GLsizei height,
2786 GLint border,
2787 GLenum format,
2788 GLenum type,
2789 const GLvoid *pixels)
2790{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002791 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002792
2793 Extents size(width, height, 1);
2794 Texture *texture =
2795 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002796 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002797 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002798}
2799
2800void Context::texImage3D(GLenum target,
2801 GLint level,
2802 GLint internalformat,
2803 GLsizei width,
2804 GLsizei height,
2805 GLsizei depth,
2806 GLint border,
2807 GLenum format,
2808 GLenum type,
2809 const GLvoid *pixels)
2810{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002811 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002812
2813 Extents size(width, height, depth);
2814 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002815 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002816 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002817}
2818
2819void Context::texSubImage2D(GLenum target,
2820 GLint level,
2821 GLint xoffset,
2822 GLint yoffset,
2823 GLsizei width,
2824 GLsizei height,
2825 GLenum format,
2826 GLenum type,
2827 const GLvoid *pixels)
2828{
2829 // Zero sized uploads are valid but no-ops
2830 if (width == 0 || height == 0)
2831 {
2832 return;
2833 }
2834
Jamie Madillad9f24e2016-02-12 09:27:24 -05002835 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002836
2837 Box area(xoffset, yoffset, 0, width, height, 1);
2838 Texture *texture =
2839 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002840 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002841 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002842}
2843
2844void Context::texSubImage3D(GLenum target,
2845 GLint level,
2846 GLint xoffset,
2847 GLint yoffset,
2848 GLint zoffset,
2849 GLsizei width,
2850 GLsizei height,
2851 GLsizei depth,
2852 GLenum format,
2853 GLenum type,
2854 const GLvoid *pixels)
2855{
2856 // Zero sized uploads are valid but no-ops
2857 if (width == 0 || height == 0 || depth == 0)
2858 {
2859 return;
2860 }
2861
Jamie Madillad9f24e2016-02-12 09:27:24 -05002862 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002863
2864 Box area(xoffset, yoffset, zoffset, width, height, depth);
2865 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002866 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002867 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002868}
2869
2870void Context::compressedTexImage2D(GLenum target,
2871 GLint level,
2872 GLenum internalformat,
2873 GLsizei width,
2874 GLsizei height,
2875 GLint border,
2876 GLsizei imageSize,
2877 const GLvoid *data)
2878{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002879 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002880
2881 Extents size(width, height, 1);
2882 Texture *texture =
2883 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002884 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2885 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002886 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002887}
2888
2889void Context::compressedTexImage3D(GLenum target,
2890 GLint level,
2891 GLenum internalformat,
2892 GLsizei width,
2893 GLsizei height,
2894 GLsizei depth,
2895 GLint border,
2896 GLsizei imageSize,
2897 const GLvoid *data)
2898{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002899 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002900
2901 Extents size(width, height, depth);
2902 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002903 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2904 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002905 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002906}
2907
2908void Context::compressedTexSubImage2D(GLenum target,
2909 GLint level,
2910 GLint xoffset,
2911 GLint yoffset,
2912 GLsizei width,
2913 GLsizei height,
2914 GLenum format,
2915 GLsizei imageSize,
2916 const GLvoid *data)
2917{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002918 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002919
2920 Box area(xoffset, yoffset, 0, width, height, 1);
2921 Texture *texture =
2922 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002923 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2924 format, imageSize,
2925 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002926}
2927
2928void Context::compressedTexSubImage3D(GLenum target,
2929 GLint level,
2930 GLint xoffset,
2931 GLint yoffset,
2932 GLint zoffset,
2933 GLsizei width,
2934 GLsizei height,
2935 GLsizei depth,
2936 GLenum format,
2937 GLsizei imageSize,
2938 const GLvoid *data)
2939{
2940 // Zero sized uploads are valid but no-ops
2941 if (width == 0 || height == 0)
2942 {
2943 return;
2944 }
2945
Jamie Madillad9f24e2016-02-12 09:27:24 -05002946 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002947
2948 Box area(xoffset, yoffset, zoffset, width, height, depth);
2949 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002950 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2951 format, imageSize,
2952 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002953}
2954
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002955void Context::generateMipmap(GLenum target)
2956{
2957 Texture *texture = getTargetTexture(target);
2958 handleError(texture->generateMipmap());
2959}
2960
Geoff Langc287ea62016-09-16 14:46:51 -04002961GLboolean Context::enableExtension(const char *name)
2962{
2963 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2964 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2965 const auto &extension = extensionInfos.at(name);
2966 ASSERT(extension.Enableable);
2967
2968 if (mExtensions.*(extension.ExtensionsMember))
2969 {
2970 // Extension already enabled
2971 return GL_TRUE;
2972 }
2973
2974 const auto &nativeExtensions = mImplementation->getNativeExtensions();
2975 if (!(nativeExtensions.*(extension.ExtensionsMember)))
2976 {
2977 // Underlying implementation does not support this valid extension
2978 return GL_FALSE;
2979 }
2980
2981 mExtensions.*(extension.ExtensionsMember) = true;
2982 updateCaps();
2983 initExtensionStrings();
2984 return GL_TRUE;
2985}
2986
Geoff Lang97073d12016-04-20 10:42:34 -07002987void Context::copyTextureCHROMIUM(GLuint sourceId,
2988 GLuint destId,
2989 GLint internalFormat,
2990 GLenum destType,
2991 GLboolean unpackFlipY,
2992 GLboolean unpackPremultiplyAlpha,
2993 GLboolean unpackUnmultiplyAlpha)
2994{
2995 syncStateForTexImage();
2996
2997 gl::Texture *sourceTexture = getTexture(sourceId);
2998 gl::Texture *destTexture = getTexture(destId);
2999 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3000 unpackPremultiplyAlpha == GL_TRUE,
3001 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3002}
3003
3004void Context::copySubTextureCHROMIUM(GLuint sourceId,
3005 GLuint destId,
3006 GLint xoffset,
3007 GLint yoffset,
3008 GLint x,
3009 GLint y,
3010 GLsizei width,
3011 GLsizei height,
3012 GLboolean unpackFlipY,
3013 GLboolean unpackPremultiplyAlpha,
3014 GLboolean unpackUnmultiplyAlpha)
3015{
3016 // Zero sized copies are valid but no-ops
3017 if (width == 0 || height == 0)
3018 {
3019 return;
3020 }
3021
3022 syncStateForTexImage();
3023
3024 gl::Texture *sourceTexture = getTexture(sourceId);
3025 gl::Texture *destTexture = getTexture(destId);
3026 Offset offset(xoffset, yoffset, 0);
3027 Rectangle area(x, y, width, height);
3028 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3029 unpackPremultiplyAlpha == GL_TRUE,
3030 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3031}
3032
Geoff Lang47110bf2016-04-20 11:13:22 -07003033void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3034{
3035 syncStateForTexImage();
3036
3037 gl::Texture *sourceTexture = getTexture(sourceId);
3038 gl::Texture *destTexture = getTexture(destId);
3039 handleError(destTexture->copyCompressedTexture(sourceTexture));
3040}
3041
Geoff Lang496c02d2016-10-20 11:38:11 -07003042void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003043{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003044 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003045 ASSERT(buffer);
3046
Geoff Lang496c02d2016-10-20 11:38:11 -07003047 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003048}
3049
3050GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3051{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003052 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003053 ASSERT(buffer);
3054
3055 Error error = buffer->map(access);
3056 if (error.isError())
3057 {
Jamie Madill437fa652016-05-03 15:13:24 -04003058 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003059 return nullptr;
3060 }
3061
3062 return buffer->getMapPointer();
3063}
3064
3065GLboolean Context::unmapBuffer(GLenum target)
3066{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003067 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003068 ASSERT(buffer);
3069
3070 GLboolean result;
3071 Error error = buffer->unmap(&result);
3072 if (error.isError())
3073 {
Jamie Madill437fa652016-05-03 15:13:24 -04003074 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003075 return GL_FALSE;
3076 }
3077
3078 return result;
3079}
3080
3081GLvoid *Context::mapBufferRange(GLenum target,
3082 GLintptr offset,
3083 GLsizeiptr length,
3084 GLbitfield access)
3085{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003086 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003087 ASSERT(buffer);
3088
3089 Error error = buffer->mapRange(offset, length, access);
3090 if (error.isError())
3091 {
Jamie Madill437fa652016-05-03 15:13:24 -04003092 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003093 return nullptr;
3094 }
3095
3096 return buffer->getMapPointer();
3097}
3098
3099void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3100{
3101 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3102}
3103
Jamie Madillad9f24e2016-02-12 09:27:24 -05003104void Context::syncStateForReadPixels()
3105{
3106 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3107}
3108
3109void Context::syncStateForTexImage()
3110{
3111 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3112}
3113
3114void Context::syncStateForClear()
3115{
3116 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3117}
3118
3119void Context::syncStateForBlit()
3120{
3121 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3122}
3123
Jamie Madillc20ab272016-06-09 07:20:46 -07003124void Context::activeTexture(GLenum texture)
3125{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003126 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003127}
3128
3129void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3130{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003131 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003132}
3133
3134void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3135{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003136 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003137}
3138
3139void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3140{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003141 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003142}
3143
3144void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3145{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003146 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003147}
3148
3149void Context::clearDepthf(GLclampf depth)
3150{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003151 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003152}
3153
3154void Context::clearStencil(GLint s)
3155{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003156 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003157}
3158
3159void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3160{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003161 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003162}
3163
3164void Context::cullFace(GLenum mode)
3165{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003166 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003167}
3168
3169void Context::depthFunc(GLenum func)
3170{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003171 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003172}
3173
3174void Context::depthMask(GLboolean flag)
3175{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003176 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003177}
3178
3179void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3180{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003181 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003182}
3183
3184void Context::disable(GLenum cap)
3185{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003186 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003187}
3188
3189void Context::disableVertexAttribArray(GLuint index)
3190{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003191 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003192}
3193
3194void Context::enable(GLenum cap)
3195{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003196 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003197}
3198
3199void Context::enableVertexAttribArray(GLuint index)
3200{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003201 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003202}
3203
3204void Context::frontFace(GLenum mode)
3205{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003206 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003207}
3208
3209void Context::hint(GLenum target, GLenum mode)
3210{
3211 switch (target)
3212 {
3213 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003214 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003215 break;
3216
3217 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003218 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003219 break;
3220
3221 default:
3222 UNREACHABLE();
3223 return;
3224 }
3225}
3226
3227void Context::lineWidth(GLfloat width)
3228{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003229 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003230}
3231
3232void Context::pixelStorei(GLenum pname, GLint param)
3233{
3234 switch (pname)
3235 {
3236 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003237 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003238 break;
3239
3240 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003241 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003242 break;
3243
3244 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003245 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003246 break;
3247
3248 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003249 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003250 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003251 break;
3252
3253 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003254 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003255 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003256 break;
3257
3258 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003259 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003260 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003261 break;
3262
3263 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003264 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003265 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003266 break;
3267
3268 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003269 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003270 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003271 break;
3272
3273 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003274 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003275 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003276 break;
3277
3278 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003279 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003280 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003281 break;
3282
3283 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003284 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003285 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003286 break;
3287
3288 default:
3289 UNREACHABLE();
3290 return;
3291 }
3292}
3293
3294void Context::polygonOffset(GLfloat factor, GLfloat units)
3295{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003297}
3298
3299void Context::sampleCoverage(GLclampf value, GLboolean invert)
3300{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003301 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003302}
3303
3304void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3305{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003306 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003307}
3308
3309void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3310{
3311 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3312 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003313 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003314 }
3315
3316 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3317 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003318 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003319 }
3320}
3321
3322void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3323{
3324 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3325 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003326 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003327 }
3328
3329 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3330 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003331 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003332 }
3333}
3334
3335void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3336{
3337 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3338 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340 }
3341
3342 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3343 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345 }
3346}
3347
3348void Context::vertexAttrib1f(GLuint index, GLfloat x)
3349{
3350 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003351 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003352}
3353
3354void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3355{
3356 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003357 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003358}
3359
3360void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3361{
3362 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003363 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003364}
3365
3366void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3367{
3368 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370}
3371
3372void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3373{
3374 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003375 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003376}
3377
3378void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3379{
3380 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003381 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003382}
3383
3384void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3385{
3386 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003387 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003388}
3389
3390void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3391{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003392 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003393}
3394
3395void Context::vertexAttribPointer(GLuint index,
3396 GLint size,
3397 GLenum type,
3398 GLboolean normalized,
3399 GLsizei stride,
3400 const GLvoid *ptr)
3401{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003402 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3403 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003404}
3405
3406void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3407{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003408 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003409}
3410
3411void Context::vertexAttribIPointer(GLuint index,
3412 GLint size,
3413 GLenum type,
3414 GLsizei stride,
3415 const GLvoid *pointer)
3416{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003417 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3418 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003419}
3420
3421void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3422{
3423 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425}
3426
3427void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3428{
3429 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003430 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003431}
3432
3433void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3434{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003435 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003436}
3437
3438void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3439{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003440 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003441}
3442
3443void Context::debugMessageControl(GLenum source,
3444 GLenum type,
3445 GLenum severity,
3446 GLsizei count,
3447 const GLuint *ids,
3448 GLboolean enabled)
3449{
3450 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003451 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3452 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003453}
3454
3455void Context::debugMessageInsert(GLenum source,
3456 GLenum type,
3457 GLuint id,
3458 GLenum severity,
3459 GLsizei length,
3460 const GLchar *buf)
3461{
3462 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003463 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003464}
3465
3466void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3467{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003468 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003469}
3470
3471GLuint Context::getDebugMessageLog(GLuint count,
3472 GLsizei bufSize,
3473 GLenum *sources,
3474 GLenum *types,
3475 GLuint *ids,
3476 GLenum *severities,
3477 GLsizei *lengths,
3478 GLchar *messageLog)
3479{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003480 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3481 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003482}
3483
3484void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3485{
3486 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003487 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003488}
3489
3490void Context::popDebugGroup()
3491{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003492 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003493}
3494
Jamie Madill29639852016-09-02 15:00:09 -04003495void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3496{
3497 Buffer *buffer = mGLState.getTargetBuffer(target);
3498 ASSERT(buffer);
3499 handleError(buffer->bufferData(target, data, size, usage));
3500}
3501
3502void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3503{
3504 if (data == nullptr)
3505 {
3506 return;
3507 }
3508
3509 Buffer *buffer = mGLState.getTargetBuffer(target);
3510 ASSERT(buffer);
3511 handleError(buffer->bufferSubData(target, data, size, offset));
3512}
3513
Jamie Madillef300b12016-10-07 15:12:09 -04003514void Context::attachShader(GLuint program, GLuint shader)
3515{
3516 auto programObject = mResourceManager->getProgram(program);
3517 auto shaderObject = mResourceManager->getShader(shader);
3518 ASSERT(programObject && shaderObject);
3519 programObject->attachShader(shaderObject);
3520}
3521
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003522const Workarounds &Context::getWorkarounds() const
3523{
3524 return mWorkarounds;
3525}
3526
Jamie Madillb0817d12016-11-01 15:48:31 -04003527void Context::copyBufferSubData(GLenum readTarget,
3528 GLenum writeTarget,
3529 GLintptr readOffset,
3530 GLintptr writeOffset,
3531 GLsizeiptr size)
3532{
3533 // if size is zero, the copy is a successful no-op
3534 if (size == 0)
3535 {
3536 return;
3537 }
3538
3539 // TODO(jmadill): cache these.
3540 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3541 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3542
3543 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3544}
3545
Jamie Madillc29968b2016-01-20 11:17:23 -05003546} // namespace gl