blob: 48e39337a7206442b0a7670dce9fc095648d1d36 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050021#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050022#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050029#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/ResourceManager.h"
31#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050032#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050033#include "libANGLE/Texture.h"
34#include "libANGLE/TransformFeedback.h"
35#include "libANGLE/VertexArray.h"
36#include "libANGLE/formatutils.h"
37#include "libANGLE/validationES.h"
Jamie Madill437fa652016-05-03 15:13:24 -040038#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040039#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030040#include "libANGLE/queryconversions.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000041
Geoff Langf6db0982015-08-25 13:04:00 -040042namespace
43{
44
Ian Ewell3ffd78b2016-01-22 16:09:42 -050045template <typename T>
Sami Väisänend59ca052016-06-21 16:10:00 +030046std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
47 GLsizei numPaths,
48 const void *paths,
49 GLuint pathBase)
50{
51 std::vector<gl::Path *> ret;
52 ret.reserve(numPaths);
53
54 const auto *nameArray = static_cast<const T *>(paths);
55
56 for (GLsizei i = 0; i < numPaths; ++i)
57 {
58 const GLuint pathName = nameArray[i] + pathBase;
59
60 ret.push_back(resourceManager.getPath(pathName));
61 }
62
63 return ret;
64}
65
66std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
67 GLsizei numPaths,
68 GLenum pathNameType,
69 const void *paths,
70 GLuint pathBase)
71{
72 switch (pathNameType)
73 {
74 case GL_UNSIGNED_BYTE:
75 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
76
77 case GL_BYTE:
78 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_UNSIGNED_SHORT:
81 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_SHORT:
84 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_UNSIGNED_INT:
87 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_INT:
90 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
91 }
92
93 UNREACHABLE();
94 return std::vector<gl::Path *>();
95}
96
97template <typename T>
Ian Ewell3ffd78b2016-01-22 16:09:42 -050098gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
99{
100 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
101 ASSERT(queryObject != nullptr);
102
103 switch (pname)
104 {
105 case GL_QUERY_RESULT_EXT:
106 return queryObject->getResult(params);
107 case GL_QUERY_RESULT_AVAILABLE_EXT:
108 {
109 bool available;
110 gl::Error error = queryObject->isResultAvailable(&available);
111 if (!error.isError())
112 {
113 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
114 }
115 return error;
116 }
117 default:
118 UNREACHABLE();
119 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
120 }
121}
122
Geoff Langf6db0982015-08-25 13:04:00 -0400123void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
124{
Geoff Lang1a683462015-09-29 15:09:59 -0400125 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400126 {
127 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
128 tfBufferIndex++)
129 {
130 const OffsetBindingPointer<gl::Buffer> &buffer =
131 transformFeedback->getIndexedBuffer(tfBufferIndex);
132 if (buffer.get() != nullptr)
133 {
134 buffer->onTransformFeedback();
135 }
136 }
137 }
138}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500139
140// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300141EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500142{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400143 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144}
145
Martin Radev1be913c2016-07-11 17:59:16 +0300146EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
147{
148 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
149}
150
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151GLenum GetResetStrategy(const egl::AttributeMap &attribs)
152{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400153 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
154 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500155 switch (attrib)
156 {
157 case EGL_NO_RESET_NOTIFICATION:
158 return GL_NO_RESET_NOTIFICATION_EXT;
159 case EGL_LOSE_CONTEXT_ON_RESET:
160 return GL_LOSE_CONTEXT_ON_RESET_EXT;
161 default:
162 UNREACHABLE();
163 return GL_NONE;
164 }
165}
166
167bool GetRobustAccess(const egl::AttributeMap &attribs)
168{
169 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
170}
171
172bool GetDebug(const egl::AttributeMap &attribs)
173{
174 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
175}
176
177bool GetNoError(const egl::AttributeMap &attribs)
178{
179 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
180}
181
Geoff Langc287ea62016-09-16 14:46:51 -0400182bool GetWebGLContext(const egl::AttributeMap &attribs)
183{
184 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
185}
186
Martin Radev9d901792016-07-15 15:58:58 +0300187std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
188{
189 std::string labelName;
190 if (label != nullptr)
191 {
192 size_t labelLength = length < 0 ? strlen(label) : length;
193 labelName = std::string(label, labelLength);
194 }
195 return labelName;
196}
197
198void GetObjectLabelBase(const std::string &objectLabel,
199 GLsizei bufSize,
200 GLsizei *length,
201 GLchar *label)
202{
203 size_t writeLength = objectLabel.length();
204 if (label != nullptr && bufSize > 0)
205 {
206 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
207 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
208 label[writeLength] = '\0';
209 }
210
211 if (length != nullptr)
212 {
213 *length = static_cast<GLsizei>(writeLength);
214 }
215}
216
Geoff Langf6db0982015-08-25 13:04:00 -0400217} // anonymous namespace
218
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000219namespace gl
220{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000221
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400222Context::Context(rx::EGLImplFactory *implFactory,
223 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400224 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500225 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300226
227 : ValidationContext(GetClientMajorVersion(attribs),
228 GetClientMinorVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700229 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500230 mCaps,
231 mTextureCaps,
232 mExtensions,
233 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500234 mLimitations,
235 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700236 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500237 mCompiler(nullptr),
Martin Radev1be913c2016-07-11 17:59:16 +0300238 mClientMajorVersion(GetClientMajorVersion(attribs)),
239 mClientMinorVersion(GetClientMinorVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400240 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500241 mClientType(EGL_OPENGL_ES_API),
242 mHasBeenCurrent(false),
243 mContextLost(false),
244 mResetStatus(GL_NO_ERROR),
245 mResetStrategy(GetResetStrategy(attribs)),
246 mRobustAccess(GetRobustAccess(attribs)),
247 mCurrentSurface(nullptr),
248 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000249{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500250 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000251
Geoff Langc287ea62016-09-16 14:46:51 -0400252 initCaps(GetWebGLContext(attribs));
Geoff Langc0b9ef42014-07-02 10:02:37 -0400253
Martin Radev1be913c2016-07-11 17:59:16 +0300254 mGLState.initialize(mCaps, mExtensions, mClientMajorVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100255
Shannon Woods53a94a82014-06-24 15:20:36 -0400256 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400257
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400258 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000259 {
260 mResourceManager = shareContext->mResourceManager;
261 mResourceManager->addRef();
262 }
263 else
264 {
Jamie Madill901b3792016-05-26 09:20:40 -0400265 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000266 }
267
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700268 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400269
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000270 // [OpenGL ES 2.0.24] section 3.7 page 83:
271 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
272 // and cube map texture state vectors respectively associated with them.
273 // In order that access to these initial textures not be lost, they are treated as texture
274 // objects all of whose names are 0.
275
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400276 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500277 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500278
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400279 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500280 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400281
Martin Radev1be913c2016-07-11 17:59:16 +0300282 if (mClientMajorVersion >= 3)
Geoff Lang76b10c92014-09-05 16:28:14 -0400283 {
284 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400285 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500286 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400287
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400288 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500289 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400290 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000291
Ian Ewellbda75592016-04-18 17:25:54 -0400292 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
293 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTextureExternal =
295 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400296 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
297 }
298
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700299 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500300
Jamie Madill57a89722013-07-02 11:57:03 -0400301 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000302 bindArrayBuffer(0);
303 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400304
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000305 bindRenderbuffer(0);
306
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000307 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400308 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000309 {
310 bindIndexedUniformBuffer(0, i, 0, -1);
311 }
312
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000313 bindCopyReadBuffer(0);
314 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000315 bindPixelPackBuffer(0);
316 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000317
Martin Radev1be913c2016-07-11 17:59:16 +0300318 if (mClientMajorVersion >= 3)
Geoff Lang1a683462015-09-29 15:09:59 -0400319 {
320 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
321 // In the initial state, a default transform feedback object is bound and treated as
322 // a transform feedback object with a name of zero. That object is bound any time
323 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400324 bindTransformFeedback(0);
325 }
Geoff Langc8058452014-02-03 12:04:11 -0500326
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700327 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500328
329 // Initialize dirty bit masks
330 // TODO(jmadill): additional ES3 state
331 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
332 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
333 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
334 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
335 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
336 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400337 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500338 // No dirty objects.
339
340 // Readpixels uses the pack state and read FBO
341 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
342 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
343 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
344 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
345 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400346 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500347 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
348
349 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
350 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
351 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
352 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
353 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
354 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
355 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
356 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
357 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
358 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
359 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
360 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
361
362 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
363 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
364 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
365 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400366
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400367 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000368}
369
370Context::~Context()
371{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700372 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000373
Corentin Wallez37c39792015-08-20 14:19:46 -0400374 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000375 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400376 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400377 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400378 {
379 SafeDelete(framebuffer.second);
380 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000381 }
382
Corentin Wallez80b24112015-08-25 16:41:57 -0400383 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000384 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400385 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000386 }
387
Corentin Wallez80b24112015-08-25 16:41:57 -0400388 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000389 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400390 if (query.second != nullptr)
391 {
392 query.second->release();
393 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000394 }
395
Corentin Wallez80b24112015-08-25 16:41:57 -0400396 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400397 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400398 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400399 }
400
Corentin Wallez80b24112015-08-25 16:41:57 -0400401 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500402 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500403 if (transformFeedback.second != nullptr)
404 {
405 transformFeedback.second->release();
406 }
Geoff Langc8058452014-02-03 12:04:11 -0500407 }
408
Jamie Madilldedd7b92014-11-05 16:30:36 -0500409 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400410 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500411 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400412 }
413 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000414
Corentin Wallez51706ea2015-08-07 14:39:22 -0400415 if (mCurrentSurface != nullptr)
416 {
417 releaseSurface();
418 }
419
Jamie Madill1e9ae072014-11-06 15:27:21 -0500420 if (mResourceManager)
421 {
422 mResourceManager->release();
423 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500424
425 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426}
427
daniel@transgaming.comad629872012-11-28 19:32:06 +0000428void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429{
Jamie Madill77a72f62015-04-14 11:18:32 -0400430 ASSERT(surface != nullptr);
431
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000432 if (!mHasBeenCurrent)
433 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000434 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400435 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000436
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700437 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
438 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000439
440 mHasBeenCurrent = true;
441 }
442
Jamie Madill1b94d432015-08-07 13:23:23 -0400443 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700444 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400445
Corentin Wallez51706ea2015-08-07 14:39:22 -0400446 if (mCurrentSurface)
447 {
448 releaseSurface();
449 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000450 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400451 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000452
Corentin Wallez37c39792015-08-20 14:19:46 -0400453 // Update default framebuffer, the binding of the previous default
454 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400455 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400456 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700457 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400458 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700459 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400460 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700461 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400462 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700463 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400464 }
465 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400466 }
Ian Ewell292f0052016-02-04 10:37:32 -0500467
468 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700469 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000470}
471
Jamie Madill77a72f62015-04-14 11:18:32 -0400472void Context::releaseSurface()
473{
Corentin Wallez37c39792015-08-20 14:19:46 -0400474 ASSERT(mCurrentSurface != nullptr);
475
476 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400477 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400478 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700479 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400480 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700481 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400482 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700483 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400484 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700485 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400486 }
487 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400488 }
489
Corentin Wallez51706ea2015-08-07 14:39:22 -0400490 mCurrentSurface->setIsCurrent(false);
491 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400492}
493
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000494GLuint Context::createBuffer()
495{
496 return mResourceManager->createBuffer();
497}
498
499GLuint Context::createProgram()
500{
Jamie Madill901b3792016-05-26 09:20:40 -0400501 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000502}
503
504GLuint Context::createShader(GLenum type)
505{
Jamie Madill901b3792016-05-26 09:20:40 -0400506 return mResourceManager->createShader(mImplementation.get(),
507 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000508}
509
510GLuint Context::createTexture()
511{
512 return mResourceManager->createTexture();
513}
514
515GLuint Context::createRenderbuffer()
516{
517 return mResourceManager->createRenderbuffer();
518}
519
Geoff Lang882033e2014-09-30 11:26:07 -0400520GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400521{
Jamie Madill901b3792016-05-26 09:20:40 -0400522 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400523
Cooper Partind8e62a32015-01-29 15:21:25 -0800524 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400525}
526
Sami Väisänene45e53b2016-05-25 10:36:04 +0300527GLuint Context::createPaths(GLsizei range)
528{
529 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
530 if (resultOrError.isError())
531 {
532 handleError(resultOrError.getError());
533 return 0;
534 }
535 return resultOrError.getResult();
536}
537
Jamie Madill57a89722013-07-02 11:57:03 -0400538GLuint Context::createVertexArray()
539{
Geoff Lang36167ab2015-12-07 10:27:14 -0500540 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
541 mVertexArrayMap[vertexArray] = nullptr;
542 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400543}
544
Jamie Madilldc356042013-07-19 16:36:57 -0400545GLuint Context::createSampler()
546{
547 return mResourceManager->createSampler();
548}
549
Geoff Langc8058452014-02-03 12:04:11 -0500550GLuint Context::createTransformFeedback()
551{
Geoff Lang36167ab2015-12-07 10:27:14 -0500552 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
553 mTransformFeedbackMap[transformFeedback] = nullptr;
554 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500555}
556
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000557// Returns an unused framebuffer name
558GLuint Context::createFramebuffer()
559{
560 GLuint handle = mFramebufferHandleAllocator.allocate();
561
562 mFramebufferMap[handle] = NULL;
563
564 return handle;
565}
566
Jamie Madill33dc8432013-07-26 11:55:05 -0400567GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000568{
Jamie Madill33dc8432013-07-26 11:55:05 -0400569 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000570
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400571 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000572
573 return handle;
574}
575
576// Returns an unused query name
577GLuint Context::createQuery()
578{
579 GLuint handle = mQueryHandleAllocator.allocate();
580
581 mQueryMap[handle] = NULL;
582
583 return handle;
584}
585
586void Context::deleteBuffer(GLuint buffer)
587{
588 if (mResourceManager->getBuffer(buffer))
589 {
590 detachBuffer(buffer);
591 }
Jamie Madill893ab082014-05-16 16:56:10 -0400592
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000593 mResourceManager->deleteBuffer(buffer);
594}
595
596void Context::deleteShader(GLuint shader)
597{
598 mResourceManager->deleteShader(shader);
599}
600
601void Context::deleteProgram(GLuint program)
602{
603 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000604}
605
606void Context::deleteTexture(GLuint texture)
607{
608 if (mResourceManager->getTexture(texture))
609 {
610 detachTexture(texture);
611 }
612
613 mResourceManager->deleteTexture(texture);
614}
615
616void Context::deleteRenderbuffer(GLuint renderbuffer)
617{
618 if (mResourceManager->getRenderbuffer(renderbuffer))
619 {
620 detachRenderbuffer(renderbuffer);
621 }
Jamie Madill893ab082014-05-16 16:56:10 -0400622
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000623 mResourceManager->deleteRenderbuffer(renderbuffer);
624}
625
Jamie Madillcd055f82013-07-26 11:55:15 -0400626void Context::deleteFenceSync(GLsync fenceSync)
627{
628 // The spec specifies the underlying Fence object is not deleted until all current
629 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
630 // and since our API is currently designed for being called from a single thread, we can delete
631 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700632 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400633}
634
Sami Väisänene45e53b2016-05-25 10:36:04 +0300635void Context::deletePaths(GLuint first, GLsizei range)
636{
637 mResourceManager->deletePaths(first, range);
638}
639
640bool Context::hasPathData(GLuint path) const
641{
642 const auto *pathObj = mResourceManager->getPath(path);
643 if (pathObj == nullptr)
644 return false;
645
646 return pathObj->hasPathData();
647}
648
649bool Context::hasPath(GLuint path) const
650{
651 return mResourceManager->hasPath(path);
652}
653
654void Context::setPathCommands(GLuint path,
655 GLsizei numCommands,
656 const GLubyte *commands,
657 GLsizei numCoords,
658 GLenum coordType,
659 const void *coords)
660{
661 auto *pathObject = mResourceManager->getPath(path);
662
663 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
664}
665
666void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
667{
668 auto *pathObj = mResourceManager->getPath(path);
669
670 switch (pname)
671 {
672 case GL_PATH_STROKE_WIDTH_CHROMIUM:
673 pathObj->setStrokeWidth(value);
674 break;
675 case GL_PATH_END_CAPS_CHROMIUM:
676 pathObj->setEndCaps(static_cast<GLenum>(value));
677 break;
678 case GL_PATH_JOIN_STYLE_CHROMIUM:
679 pathObj->setJoinStyle(static_cast<GLenum>(value));
680 break;
681 case GL_PATH_MITER_LIMIT_CHROMIUM:
682 pathObj->setMiterLimit(value);
683 break;
684 case GL_PATH_STROKE_BOUND_CHROMIUM:
685 pathObj->setStrokeBound(value);
686 break;
687 default:
688 UNREACHABLE();
689 break;
690 }
691}
692
693void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
694{
695 const auto *pathObj = mResourceManager->getPath(path);
696
697 switch (pname)
698 {
699 case GL_PATH_STROKE_WIDTH_CHROMIUM:
700 *value = pathObj->getStrokeWidth();
701 break;
702 case GL_PATH_END_CAPS_CHROMIUM:
703 *value = static_cast<GLfloat>(pathObj->getEndCaps());
704 break;
705 case GL_PATH_JOIN_STYLE_CHROMIUM:
706 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
707 break;
708 case GL_PATH_MITER_LIMIT_CHROMIUM:
709 *value = pathObj->getMiterLimit();
710 break;
711 case GL_PATH_STROKE_BOUND_CHROMIUM:
712 *value = pathObj->getStrokeBound();
713 break;
714 default:
715 UNREACHABLE();
716 break;
717 }
718}
719
720void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
721{
722 mGLState.setPathStencilFunc(func, ref, mask);
723}
724
Jamie Madill57a89722013-07-02 11:57:03 -0400725void Context::deleteVertexArray(GLuint vertexArray)
726{
Geoff Lang36167ab2015-12-07 10:27:14 -0500727 auto iter = mVertexArrayMap.find(vertexArray);
728 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000729 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500730 VertexArray *vertexArrayObject = iter->second;
731 if (vertexArrayObject != nullptr)
732 {
733 detachVertexArray(vertexArray);
734 delete vertexArrayObject;
735 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000736
Geoff Lang36167ab2015-12-07 10:27:14 -0500737 mVertexArrayMap.erase(iter);
738 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400739 }
740}
741
Jamie Madilldc356042013-07-19 16:36:57 -0400742void Context::deleteSampler(GLuint sampler)
743{
744 if (mResourceManager->getSampler(sampler))
745 {
746 detachSampler(sampler);
747 }
748
749 mResourceManager->deleteSampler(sampler);
750}
751
Geoff Langc8058452014-02-03 12:04:11 -0500752void Context::deleteTransformFeedback(GLuint transformFeedback)
753{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500754 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500755 if (iter != mTransformFeedbackMap.end())
756 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500757 TransformFeedback *transformFeedbackObject = iter->second;
758 if (transformFeedbackObject != nullptr)
759 {
760 detachTransformFeedback(transformFeedback);
761 transformFeedbackObject->release();
762 }
763
Geoff Lang50b3fe82015-12-08 14:49:12 +0000764 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500765 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500766 }
767}
768
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000769void Context::deleteFramebuffer(GLuint framebuffer)
770{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500771 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000772
773 if (framebufferObject != mFramebufferMap.end())
774 {
775 detachFramebuffer(framebuffer);
776
777 mFramebufferHandleAllocator.release(framebufferObject->first);
778 delete framebufferObject->second;
779 mFramebufferMap.erase(framebufferObject);
780 }
781}
782
Jamie Madill33dc8432013-07-26 11:55:05 -0400783void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000784{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500785 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000786
Jamie Madill33dc8432013-07-26 11:55:05 -0400787 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000788 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400789 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000790 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400791 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000792 }
793}
794
795void Context::deleteQuery(GLuint query)
796{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500797 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798 if (queryObject != mQueryMap.end())
799 {
800 mQueryHandleAllocator.release(queryObject->first);
801 if (queryObject->second)
802 {
803 queryObject->second->release();
804 }
805 mQueryMap.erase(queryObject);
806 }
807}
808
Geoff Lang70d0f492015-12-10 17:45:46 -0500809Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810{
811 return mResourceManager->getBuffer(handle);
812}
813
Geoff Lang48dcae72014-02-05 16:28:24 -0500814Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815{
816 return mResourceManager->getShader(handle);
817}
818
Geoff Lang48dcae72014-02-05 16:28:24 -0500819Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820{
821 return mResourceManager->getProgram(handle);
822}
823
Jamie Madill570f7c82014-07-03 10:38:54 -0400824Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825{
826 return mResourceManager->getTexture(handle);
827}
828
Geoff Lang70d0f492015-12-10 17:45:46 -0500829Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000830{
831 return mResourceManager->getRenderbuffer(handle);
832}
833
Jamie Madillcd055f82013-07-26 11:55:15 -0400834FenceSync *Context::getFenceSync(GLsync handle) const
835{
Minmin Gong794e0002015-04-07 18:31:54 -0700836 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400837}
838
Jamie Madill57a89722013-07-02 11:57:03 -0400839VertexArray *Context::getVertexArray(GLuint handle) const
840{
841 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500842 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400843}
844
Jamie Madilldc356042013-07-19 16:36:57 -0400845Sampler *Context::getSampler(GLuint handle) const
846{
847 return mResourceManager->getSampler(handle);
848}
849
Geoff Langc8058452014-02-03 12:04:11 -0500850TransformFeedback *Context::getTransformFeedback(GLuint handle) const
851{
Geoff Lang36167ab2015-12-07 10:27:14 -0500852 auto iter = mTransformFeedbackMap.find(handle);
853 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500854}
855
Geoff Lang70d0f492015-12-10 17:45:46 -0500856LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
857{
858 switch (identifier)
859 {
860 case GL_BUFFER:
861 return getBuffer(name);
862 case GL_SHADER:
863 return getShader(name);
864 case GL_PROGRAM:
865 return getProgram(name);
866 case GL_VERTEX_ARRAY:
867 return getVertexArray(name);
868 case GL_QUERY:
869 return getQuery(name);
870 case GL_TRANSFORM_FEEDBACK:
871 return getTransformFeedback(name);
872 case GL_SAMPLER:
873 return getSampler(name);
874 case GL_TEXTURE:
875 return getTexture(name);
876 case GL_RENDERBUFFER:
877 return getRenderbuffer(name);
878 case GL_FRAMEBUFFER:
879 return getFramebuffer(name);
880 default:
881 UNREACHABLE();
882 return nullptr;
883 }
884}
885
886LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
887{
888 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
889}
890
Martin Radev9d901792016-07-15 15:58:58 +0300891void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
892{
893 LabeledObject *object = getLabeledObject(identifier, name);
894 ASSERT(object != nullptr);
895
896 std::string labelName = GetObjectLabelFromPointer(length, label);
897 object->setLabel(labelName);
898}
899
900void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
901{
902 LabeledObject *object = getLabeledObjectFromPtr(ptr);
903 ASSERT(object != nullptr);
904
905 std::string labelName = GetObjectLabelFromPointer(length, label);
906 object->setLabel(labelName);
907}
908
909void Context::getObjectLabel(GLenum identifier,
910 GLuint name,
911 GLsizei bufSize,
912 GLsizei *length,
913 GLchar *label) const
914{
915 LabeledObject *object = getLabeledObject(identifier, name);
916 ASSERT(object != nullptr);
917
918 const std::string &objectLabel = object->getLabel();
919 GetObjectLabelBase(objectLabel, bufSize, length, label);
920}
921
922void Context::getObjectPtrLabel(const void *ptr,
923 GLsizei bufSize,
924 GLsizei *length,
925 GLchar *label) const
926{
927 LabeledObject *object = getLabeledObjectFromPtr(ptr);
928 ASSERT(object != nullptr);
929
930 const std::string &objectLabel = object->getLabel();
931 GetObjectLabelBase(objectLabel, bufSize, length, label);
932}
933
Jamie Madilldc356042013-07-19 16:36:57 -0400934bool Context::isSampler(GLuint samplerName) const
935{
936 return mResourceManager->isSampler(samplerName);
937}
938
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500939void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000940{
Jamie Madill901b3792016-05-26 09:20:40 -0400941 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700942 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000943}
944
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500945void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000946{
Jamie Madill901b3792016-05-26 09:20:40 -0400947 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700948 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000949}
950
Jamie Madilldedd7b92014-11-05 16:30:36 -0500951void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500953 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954
Jamie Madilldedd7b92014-11-05 16:30:36 -0500955 if (handle == 0)
956 {
957 texture = mZeroTextures[target].get();
958 }
959 else
960 {
Jamie Madill901b3792016-05-26 09:20:40 -0400961 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500962 }
963
964 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700965 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000966}
967
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500968void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000969{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500970 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700971 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000972}
973
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500974void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000975{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500976 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700977 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978}
979
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500980void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981{
Jamie Madill901b3792016-05-26 09:20:40 -0400982 Renderbuffer *renderbuffer =
983 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700984 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000985}
986
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500987void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400988{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500989 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700990 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400991}
992
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500993void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400994{
Geoff Lang76b10c92014-09-05 16:28:14 -0400995 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400996 Sampler *sampler =
997 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700998 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400999}
1000
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001001void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001002{
Jamie Madill901b3792016-05-26 09:20:40 -04001003 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001004 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001005}
1006
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001007void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1008 GLuint index,
1009 GLintptr offset,
1010 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001011{
Jamie Madill901b3792016-05-26 09:20:40 -04001012 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001013 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001014}
1015
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001016void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001017{
Jamie Madill901b3792016-05-26 09:20:40 -04001018 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001019 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001020}
1021
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001022void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1023 GLuint index,
1024 GLintptr offset,
1025 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001026{
Jamie Madill901b3792016-05-26 09:20:40 -04001027 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001028 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001029}
1030
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001031void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001032{
Jamie Madill901b3792016-05-26 09:20:40 -04001033 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001034 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001038{
Jamie Madill901b3792016-05-26 09:20:40 -04001039 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001040 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001041}
1042
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001043void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001044{
Jamie Madill901b3792016-05-26 09:20:40 -04001045 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001046 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001047}
1048
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001049void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001050{
Jamie Madill901b3792016-05-26 09:20:40 -04001051 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001052 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001053}
1054
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001055void Context::useProgram(GLuint program)
1056{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001057 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001061{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001062 TransformFeedback *transformFeedback =
1063 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001064 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001065}
1066
Geoff Lang5aad9672014-09-08 11:10:42 -04001067Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001069 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001070 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001071
Geoff Lang5aad9672014-09-08 11:10:42 -04001072 // begin query
1073 Error error = queryObject->begin();
1074 if (error.isError())
1075 {
1076 return error;
1077 }
1078
1079 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001080 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001081
Geoff Lang5aad9672014-09-08 11:10:42 -04001082 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001083}
1084
Geoff Lang5aad9672014-09-08 11:10:42 -04001085Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001086{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001087 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001088 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001089
Geoff Lang5aad9672014-09-08 11:10:42 -04001090 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091
Geoff Lang5aad9672014-09-08 11:10:42 -04001092 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001093 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001094
1095 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001096}
1097
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001098Error Context::queryCounter(GLuint id, GLenum target)
1099{
1100 ASSERT(target == GL_TIMESTAMP_EXT);
1101
1102 Query *queryObject = getQuery(id, true, target);
1103 ASSERT(queryObject);
1104
1105 return queryObject->queryCounter();
1106}
1107
1108void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1109{
1110 switch (pname)
1111 {
1112 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001113 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001114 break;
1115 case GL_QUERY_COUNTER_BITS_EXT:
1116 switch (target)
1117 {
1118 case GL_TIME_ELAPSED_EXT:
1119 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1120 break;
1121 case GL_TIMESTAMP_EXT:
1122 params[0] = getExtensions().queryCounterBitsTimestamp;
1123 break;
1124 default:
1125 UNREACHABLE();
1126 params[0] = 0;
1127 break;
1128 }
1129 break;
1130 default:
1131 UNREACHABLE();
1132 return;
1133 }
1134}
1135
1136Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
1137{
1138 return GetQueryObjectParameter(this, id, pname, params);
1139}
1140
1141Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1142{
1143 return GetQueryObjectParameter(this, id, pname, params);
1144}
1145
1146Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
1147{
1148 return GetQueryObjectParameter(this, id, pname, params);
1149}
1150
1151Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
1152{
1153 return GetQueryObjectParameter(this, id, pname, params);
1154}
1155
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001156Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001157{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001158 auto framebufferIt = mFramebufferMap.find(handle);
1159 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001160}
1161
Jamie Madill33dc8432013-07-26 11:55:05 -04001162FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001163{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001164 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165
Jamie Madill33dc8432013-07-26 11:55:05 -04001166 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167 {
1168 return NULL;
1169 }
1170 else
1171 {
1172 return fence->second;
1173 }
1174}
1175
1176Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1177{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001178 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179
1180 if (query == mQueryMap.end())
1181 {
1182 return NULL;
1183 }
1184 else
1185 {
1186 if (!query->second && create)
1187 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001188 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189 query->second->addRef();
1190 }
1191 return query->second;
1192 }
1193}
1194
Geoff Lang70d0f492015-12-10 17:45:46 -05001195Query *Context::getQuery(GLuint handle) const
1196{
1197 auto iter = mQueryMap.find(handle);
1198 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1199}
1200
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001201Texture *Context::getTargetTexture(GLenum target) const
1202{
Ian Ewellbda75592016-04-18 17:25:54 -04001203 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001204 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001205}
1206
Geoff Lang76b10c92014-09-05 16:28:14 -04001207Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001208{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001209 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210}
1211
Geoff Lang492a7e42014-11-05 13:27:06 -05001212Compiler *Context::getCompiler() const
1213{
1214 return mCompiler;
1215}
1216
Jamie Madill893ab082014-05-16 16:56:10 -04001217void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218{
1219 switch (pname)
1220 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001221 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001222 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001224 mGLState.getBooleanv(pname, params);
1225 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001227}
1228
Jamie Madill893ab082014-05-16 16:56:10 -04001229void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001230{
Shannon Woods53a94a82014-06-24 15:20:36 -04001231 // Queries about context capabilities and maximums are answered by Context.
1232 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233 switch (pname)
1234 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001236 params[0] = mCaps.minAliasedLineWidth;
1237 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238 break;
1239 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001240 params[0] = mCaps.minAliasedPointSize;
1241 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001243 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001244 ASSERT(mExtensions.textureFilterAnisotropic);
1245 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001246 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001247 case GL_MAX_TEXTURE_LOD_BIAS:
1248 *params = mCaps.maxLODBias;
1249 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001250
1251 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1252 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1253 {
1254 ASSERT(mExtensions.pathRendering);
1255 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1256 memcpy(params, m, 16 * sizeof(GLfloat));
1257 }
1258 break;
1259
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001260 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001261 mGLState.getFloatv(pname, params);
1262 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001264}
1265
Jamie Madill893ab082014-05-16 16:56:10 -04001266void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267{
Shannon Woods53a94a82014-06-24 15:20:36 -04001268 // Queries about context capabilities and maximums are answered by Context.
1269 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001270
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271 switch (pname)
1272 {
Geoff Lang301d1612014-07-09 10:34:37 -04001273 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1274 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1275 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001276 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1277 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1278 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001279 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1280 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1281 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001282 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001283 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1284 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1285 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001286 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001287 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001288 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1289 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1290 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1291 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001292 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1293 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001294 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1295 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001296 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001297 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1298 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1299 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1300 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001301 case GL_MAJOR_VERSION:
1302 *params = mClientMajorVersion;
1303 break;
1304 case GL_MINOR_VERSION:
1305 *params = mClientMinorVersion;
1306 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001307 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1308 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001309 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1310 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1311 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001312 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1313 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1314 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001315 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001316 case GL_MAX_VIEWPORT_DIMS:
1317 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001318 params[0] = mCaps.maxViewportWidth;
1319 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001320 }
1321 break;
1322 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001323 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001325 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1326 *params = mResetStrategy;
1327 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001328 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001329 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001331 case GL_SHADER_BINARY_FORMATS:
1332 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1333 break;
1334 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001335 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001336 break;
1337 case GL_PROGRAM_BINARY_FORMATS:
1338 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001339 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001340 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001341 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001342 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001343
1344 // GL_KHR_debug
1345 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1346 *params = mExtensions.maxDebugMessageLength;
1347 break;
1348 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1349 *params = mExtensions.maxDebugLoggedMessages;
1350 break;
1351 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1352 *params = mExtensions.maxDebugGroupStackDepth;
1353 break;
1354 case GL_MAX_LABEL_LENGTH:
1355 *params = mExtensions.maxLabelLength;
1356 break;
1357
Ian Ewell53f59f42016-01-28 17:36:55 -05001358 // GL_EXT_disjoint_timer_query
1359 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001360 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001361 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001362 case GL_MAX_FRAMEBUFFER_WIDTH:
1363 *params = mCaps.maxFramebufferWidth;
1364 break;
1365 case GL_MAX_FRAMEBUFFER_HEIGHT:
1366 *params = mCaps.maxFramebufferHeight;
1367 break;
1368 case GL_MAX_FRAMEBUFFER_SAMPLES:
1369 *params = mCaps.maxFramebufferSamples;
1370 break;
1371 case GL_MAX_SAMPLE_MASK_WORDS:
1372 *params = mCaps.maxSampleMaskWords;
1373 break;
1374 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1375 *params = mCaps.maxColorTextureSamples;
1376 break;
1377 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1378 *params = mCaps.maxDepthTextureSamples;
1379 break;
1380 case GL_MAX_INTEGER_SAMPLES:
1381 *params = mCaps.maxIntegerSamples;
1382 break;
1383 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1384 *params = mCaps.maxVertexAttribRelativeOffset;
1385 break;
1386 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1387 *params = mCaps.maxVertexAttribBindings;
1388 break;
1389 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1390 *params = mCaps.maxVertexAttribStride;
1391 break;
1392 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1393 *params = mCaps.maxVertexAtomicCounterBuffers;
1394 break;
1395 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1396 *params = mCaps.maxVertexAtomicCounters;
1397 break;
1398 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1399 *params = mCaps.maxVertexImageUniforms;
1400 break;
1401 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1402 *params = mCaps.maxVertexShaderStorageBlocks;
1403 break;
1404 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1405 *params = mCaps.maxFragmentAtomicCounterBuffers;
1406 break;
1407 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1408 *params = mCaps.maxFragmentAtomicCounters;
1409 break;
1410 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1411 *params = mCaps.maxFragmentImageUniforms;
1412 break;
1413 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1414 *params = mCaps.maxFragmentShaderStorageBlocks;
1415 break;
1416 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1417 *params = mCaps.minProgramTextureGatherOffset;
1418 break;
1419 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1420 *params = mCaps.maxProgramTextureGatherOffset;
1421 break;
1422 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1423 *params = mCaps.maxComputeWorkGroupInvocations;
1424 break;
1425 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1426 *params = mCaps.maxComputeUniformBlocks;
1427 break;
1428 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1429 *params = mCaps.maxComputeTextureImageUnits;
1430 break;
1431 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1432 *params = mCaps.maxComputeSharedMemorySize;
1433 break;
1434 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1435 *params = mCaps.maxComputeUniformComponents;
1436 break;
1437 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1438 *params = mCaps.maxComputeAtomicCounterBuffers;
1439 break;
1440 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1441 *params = mCaps.maxComputeAtomicCounters;
1442 break;
1443 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1444 *params = mCaps.maxComputeImageUniforms;
1445 break;
1446 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1447 *params = mCaps.maxCombinedComputeUniformComponents;
1448 break;
1449 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1450 *params = mCaps.maxComputeShaderStorageBlocks;
1451 break;
1452 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1453 *params = mCaps.maxCombinedShaderOutputResources;
1454 break;
1455 case GL_MAX_UNIFORM_LOCATIONS:
1456 *params = mCaps.maxUniformLocations;
1457 break;
1458 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1459 *params = mCaps.maxAtomicCounterBufferBindings;
1460 break;
1461 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1462 *params = mCaps.maxAtomicCounterBufferSize;
1463 break;
1464 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1465 *params = mCaps.maxCombinedAtomicCounterBuffers;
1466 break;
1467 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1468 *params = mCaps.maxCombinedAtomicCounters;
1469 break;
1470 case GL_MAX_IMAGE_UNITS:
1471 *params = mCaps.maxImageUnits;
1472 break;
1473 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1474 *params = mCaps.maxCombinedImageUniforms;
1475 break;
1476 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1477 *params = mCaps.maxShaderStorageBufferBindings;
1478 break;
1479 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1480 *params = mCaps.maxCombinedShaderStorageBlocks;
1481 break;
1482 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1483 *params = mCaps.shaderStorageBufferOffsetAlignment;
1484 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001485 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001486 mGLState.getIntegerv(mState, pname, params);
1487 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001488 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001489}
1490
Jamie Madill893ab082014-05-16 16:56:10 -04001491void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001492{
Shannon Woods53a94a82014-06-24 15:20:36 -04001493 // Queries about context capabilities and maximums are answered by Context.
1494 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001495 switch (pname)
1496 {
1497 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001498 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001499 break;
1500 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001501 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001502 break;
1503 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001504 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001505 break;
1506 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001507 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001508 break;
1509 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001510 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001511 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001512
1513 // GL_EXT_disjoint_timer_query
1514 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001515 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001516 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001517
1518 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1519 *params = mCaps.maxShaderStorageBlockSize;
1520 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001521 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001522 UNREACHABLE();
1523 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001524 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001525}
1526
Geoff Lang70d0f492015-12-10 17:45:46 -05001527void Context::getPointerv(GLenum pname, void **params) const
1528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001529 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001530}
1531
Martin Radev66fb8202016-07-28 11:45:20 +03001532void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001533{
Shannon Woods53a94a82014-06-24 15:20:36 -04001534 // Queries about context capabilities and maximums are answered by Context.
1535 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001536
1537 GLenum nativeType;
1538 unsigned int numParams;
1539 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001540 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001541 ASSERT(queryStatus);
1542
1543 if (nativeType == GL_INT)
1544 {
1545 switch (target)
1546 {
1547 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1548 ASSERT(index < 3u);
1549 *data = mCaps.maxComputeWorkGroupCount[index];
1550 break;
1551 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1552 ASSERT(index < 3u);
1553 *data = mCaps.maxComputeWorkGroupSize[index];
1554 break;
1555 default:
1556 mGLState.getIntegeri_v(target, index, data);
1557 }
1558 }
1559 else
1560 {
1561 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1562 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001563}
1564
Martin Radev66fb8202016-07-28 11:45:20 +03001565void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001566{
Shannon Woods53a94a82014-06-24 15:20:36 -04001567 // Queries about context capabilities and maximums are answered by Context.
1568 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001569
1570 GLenum nativeType;
1571 unsigned int numParams;
1572 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001573 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001574 ASSERT(queryStatus);
1575
1576 if (nativeType == GL_INT_64_ANGLEX)
1577 {
1578 mGLState.getInteger64i_v(target, index, data);
1579 }
1580 else
1581 {
1582 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1583 }
1584}
1585
1586void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1587{
1588 // Queries about context capabilities and maximums are answered by Context.
1589 // Queries about current GL state values are answered by State.
1590
1591 GLenum nativeType;
1592 unsigned int numParams;
1593 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001594 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001595 ASSERT(queryStatus);
1596
1597 if (nativeType == GL_BOOL)
1598 {
1599 mGLState.getBooleani_v(target, index, data);
1600 }
1601 else
1602 {
1603 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1604 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001605}
1606
Geoff Langf6db0982015-08-25 13:04:00 -04001607Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001608{
Jamie Madill1b94d432015-08-07 13:23:23 -04001609 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001610 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001611 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001612
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001613 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001614}
1615
Geoff Langf6db0982015-08-25 13:04:00 -04001616Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1617{
1618 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001619 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001620 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001621
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001622 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001623}
1624
1625Error Context::drawElements(GLenum mode,
1626 GLsizei count,
1627 GLenum type,
1628 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001629 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001630{
Jamie Madill1b94d432015-08-07 13:23:23 -04001631 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001632 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001633}
1634
1635Error Context::drawElementsInstanced(GLenum mode,
1636 GLsizei count,
1637 GLenum type,
1638 const GLvoid *indices,
1639 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001640 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001641{
1642 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001643 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1644 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001645}
1646
1647Error Context::drawRangeElements(GLenum mode,
1648 GLuint start,
1649 GLuint end,
1650 GLsizei count,
1651 GLenum type,
1652 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001653 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001654{
1655 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001656 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001657}
1658
Geoff Lang129753a2015-01-09 16:52:09 -05001659Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001660{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001661 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001662}
1663
1664Error Context::finish()
1665{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001666 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001667}
1668
Austin Kinross6ee1e782015-05-29 17:05:37 -07001669void Context::insertEventMarker(GLsizei length, const char *marker)
1670{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001671 ASSERT(mImplementation);
1672 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001673}
1674
1675void Context::pushGroupMarker(GLsizei length, const char *marker)
1676{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001677 ASSERT(mImplementation);
1678 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001679}
1680
1681void Context::popGroupMarker()
1682{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001683 ASSERT(mImplementation);
1684 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001685}
1686
Geoff Langd8605522016-04-13 10:19:12 -04001687void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1688{
1689 Program *programObject = getProgram(program);
1690 ASSERT(programObject);
1691
1692 programObject->bindUniformLocation(location, name);
1693}
1694
Sami Väisänena797e062016-05-12 15:23:40 +03001695void Context::setCoverageModulation(GLenum components)
1696{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001697 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001698}
1699
Sami Väisänene45e53b2016-05-25 10:36:04 +03001700void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1701{
1702 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1703}
1704
1705void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1706{
1707 GLfloat I[16];
1708 angle::Matrix<GLfloat>::setToIdentity(I);
1709
1710 mGLState.loadPathRenderingMatrix(matrixMode, I);
1711}
1712
1713void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1714{
1715 const auto *pathObj = mResourceManager->getPath(path);
1716 if (!pathObj)
1717 return;
1718
1719 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1720 syncRendererState();
1721
1722 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1723}
1724
1725void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1726{
1727 const auto *pathObj = mResourceManager->getPath(path);
1728 if (!pathObj)
1729 return;
1730
1731 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1732 syncRendererState();
1733
1734 mImplementation->stencilStrokePath(pathObj, reference, mask);
1735}
1736
1737void Context::coverFillPath(GLuint path, GLenum coverMode)
1738{
1739 const auto *pathObj = mResourceManager->getPath(path);
1740 if (!pathObj)
1741 return;
1742
1743 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1744 syncRendererState();
1745
1746 mImplementation->coverFillPath(pathObj, coverMode);
1747}
1748
1749void Context::coverStrokePath(GLuint path, GLenum coverMode)
1750{
1751 const auto *pathObj = mResourceManager->getPath(path);
1752 if (!pathObj)
1753 return;
1754
1755 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1756 syncRendererState();
1757
1758 mImplementation->coverStrokePath(pathObj, coverMode);
1759}
1760
1761void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1762{
1763 const auto *pathObj = mResourceManager->getPath(path);
1764 if (!pathObj)
1765 return;
1766
1767 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1768 syncRendererState();
1769
1770 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1771}
1772
1773void Context::stencilThenCoverStrokePath(GLuint path,
1774 GLint reference,
1775 GLuint mask,
1776 GLenum coverMode)
1777{
1778 const auto *pathObj = mResourceManager->getPath(path);
1779 if (!pathObj)
1780 return;
1781
1782 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1783 syncRendererState();
1784
1785 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1786}
1787
Sami Väisänend59ca052016-06-21 16:10:00 +03001788void Context::coverFillPathInstanced(GLsizei numPaths,
1789 GLenum pathNameType,
1790 const void *paths,
1791 GLuint pathBase,
1792 GLenum coverMode,
1793 GLenum transformType,
1794 const GLfloat *transformValues)
1795{
1796 const auto &pathObjects =
1797 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1798
1799 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1800 syncRendererState();
1801
1802 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1803}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001804
Sami Väisänend59ca052016-06-21 16:10:00 +03001805void Context::coverStrokePathInstanced(GLsizei numPaths,
1806 GLenum pathNameType,
1807 const void *paths,
1808 GLuint pathBase,
1809 GLenum coverMode,
1810 GLenum transformType,
1811 const GLfloat *transformValues)
1812{
1813 const auto &pathObjects =
1814 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1815
1816 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1817 syncRendererState();
1818
1819 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1820 transformValues);
1821}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001822
Sami Väisänend59ca052016-06-21 16:10:00 +03001823void Context::stencilFillPathInstanced(GLsizei numPaths,
1824 GLenum pathNameType,
1825 const void *paths,
1826 GLuint pathBase,
1827 GLenum fillMode,
1828 GLuint mask,
1829 GLenum transformType,
1830 const GLfloat *transformValues)
1831{
1832 const auto &pathObjects =
1833 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1834
1835 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1836 syncRendererState();
1837
1838 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1839 transformValues);
1840}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001841
Sami Väisänend59ca052016-06-21 16:10:00 +03001842void Context::stencilStrokePathInstanced(GLsizei numPaths,
1843 GLenum pathNameType,
1844 const void *paths,
1845 GLuint pathBase,
1846 GLint reference,
1847 GLuint mask,
1848 GLenum transformType,
1849 const GLfloat *transformValues)
1850{
1851 const auto &pathObjects =
1852 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1853
1854 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1855 syncRendererState();
1856
1857 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1858 transformValues);
1859}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001860
Sami Väisänend59ca052016-06-21 16:10:00 +03001861void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1862 GLenum pathNameType,
1863 const void *paths,
1864 GLuint pathBase,
1865 GLenum fillMode,
1866 GLuint mask,
1867 GLenum coverMode,
1868 GLenum transformType,
1869 const GLfloat *transformValues)
1870{
1871 const auto &pathObjects =
1872 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1873
1874 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1875 syncRendererState();
1876
1877 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1878 transformType, transformValues);
1879}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001880
Sami Väisänend59ca052016-06-21 16:10:00 +03001881void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1882 GLenum pathNameType,
1883 const void *paths,
1884 GLuint pathBase,
1885 GLint reference,
1886 GLuint mask,
1887 GLenum coverMode,
1888 GLenum transformType,
1889 const GLfloat *transformValues)
1890{
1891 const auto &pathObjects =
1892 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1893
1894 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1895 syncRendererState();
1896
1897 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1898 transformType, transformValues);
1899}
1900
Sami Väisänen46eaa942016-06-29 10:26:37 +03001901void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1902{
1903 auto *programObject = getProgram(program);
1904
1905 programObject->bindFragmentInputLocation(location, name);
1906}
1907
1908void Context::programPathFragmentInputGen(GLuint program,
1909 GLint location,
1910 GLenum genMode,
1911 GLint components,
1912 const GLfloat *coeffs)
1913{
1914 auto *programObject = getProgram(program);
1915
1916 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1917}
1918
Jamie Madill437fa652016-05-03 15:13:24 -04001919void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001920{
Geoff Langda5777c2014-07-11 09:52:58 -04001921 if (error.isError())
1922 {
1923 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001924
1925 if (!error.getMessage().empty())
1926 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001927 auto *debug = &mGLState.getDebug();
1928 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1929 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001930 }
Geoff Langda5777c2014-07-11 09:52:58 -04001931 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001932}
1933
1934// Get one of the recorded errors and clear its flag, if any.
1935// [OpenGL ES 2.0.24] section 2.5 page 13.
1936GLenum Context::getError()
1937{
Geoff Langda5777c2014-07-11 09:52:58 -04001938 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001939 {
Geoff Langda5777c2014-07-11 09:52:58 -04001940 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001941 }
Geoff Langda5777c2014-07-11 09:52:58 -04001942 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001943 {
Geoff Langda5777c2014-07-11 09:52:58 -04001944 GLenum error = *mErrors.begin();
1945 mErrors.erase(mErrors.begin());
1946 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001947 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001948}
1949
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001950// NOTE: this function should not assume that this context is current!
1951void Context::markContextLost()
1952{
1953 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
1954 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
1955 mContextLost = true;
1956}
1957
1958bool Context::isContextLost()
1959{
1960 return mContextLost;
1961}
1962
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001963GLenum Context::getResetStatus()
1964{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001965 // Even if the application doesn't want to know about resets, we want to know
1966 // as it will allow us to skip all the calls.
1967 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001968 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001969 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001970 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001971 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001972 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001973
1974 // EXT_robustness, section 2.6: If the reset notification behavior is
1975 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1976 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1977 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001978 }
1979
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001980 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1981 // status should be returned at least once, and GL_NO_ERROR should be returned
1982 // once the device has finished resetting.
1983 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001984 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001985 ASSERT(mResetStatus == GL_NO_ERROR);
1986 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001987
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001988 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001989 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001990 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001991 }
1992 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001993 else if (mResetStatus != GL_NO_ERROR)
1994 {
1995 mResetStatus = mImplementation->getResetStatus();
1996 }
Jamie Madill893ab082014-05-16 16:56:10 -04001997
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001998 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001999}
2000
2001bool Context::isResetNotificationEnabled()
2002{
2003 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2004}
2005
Corentin Walleze3b10e82015-05-20 11:06:25 -04002006const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002007{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002008 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002009}
2010
2011EGLenum Context::getClientType() const
2012{
2013 return mClientType;
2014}
2015
2016EGLenum Context::getRenderBuffer() const
2017{
Corentin Wallez37c39792015-08-20 14:19:46 -04002018 auto framebufferIt = mFramebufferMap.find(0);
2019 if (framebufferIt != mFramebufferMap.end())
2020 {
2021 const Framebuffer *framebuffer = framebufferIt->second;
2022 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2023
2024 ASSERT(backAttachment != nullptr);
2025 return backAttachment->getSurface()->getRenderBuffer();
2026 }
2027 else
2028 {
2029 return EGL_NONE;
2030 }
Régis Fénéon83107972015-02-05 12:57:44 +01002031}
2032
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002033VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002034{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002035 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002036 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2037 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002038 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002039 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2040
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002041 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002042 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002043
2044 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002045}
2046
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002047TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002048{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002049 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002050 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2051 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002052 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002053 transformFeedback =
2054 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002055 transformFeedback->addRef();
2056 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002057 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002058
2059 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002060}
2061
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002062Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2063{
2064 // Can be called from Bind without a prior call to Gen.
2065 auto framebufferIt = mFramebufferMap.find(framebuffer);
2066 bool neverCreated = framebufferIt == mFramebufferMap.end();
2067 if (neverCreated || framebufferIt->second == nullptr)
2068 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002069 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002070 if (neverCreated)
2071 {
2072 mFramebufferHandleAllocator.reserve(framebuffer);
2073 mFramebufferMap[framebuffer] = newFBO;
2074 return newFBO;
2075 }
2076
2077 framebufferIt->second = newFBO;
2078 }
2079
2080 return framebufferIt->second;
2081}
2082
Geoff Lang36167ab2015-12-07 10:27:14 -05002083bool Context::isVertexArrayGenerated(GLuint vertexArray)
2084{
2085 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2086}
2087
2088bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2089{
2090 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2091}
2092
Shannon Woods53a94a82014-06-24 15:20:36 -04002093void Context::detachTexture(GLuint texture)
2094{
2095 // Simple pass-through to State's detachTexture method, as textures do not require
2096 // allocation map management either here or in the resource manager at detach time.
2097 // Zero textures are held by the Context, and we don't attempt to request them from
2098 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002099 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002100}
2101
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002102void Context::detachBuffer(GLuint buffer)
2103{
Yuly Novikov5807a532015-12-03 13:01:22 -05002104 // Simple pass-through to State's detachBuffer method, since
2105 // only buffer attachments to container objects that are bound to the current context
2106 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002107
Yuly Novikov5807a532015-12-03 13:01:22 -05002108 // [OpenGL ES 3.2] section 5.1.2 page 45:
2109 // Attachments to unbound container objects, such as
2110 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2111 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002112 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002113}
2114
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002115void Context::detachFramebuffer(GLuint framebuffer)
2116{
Shannon Woods53a94a82014-06-24 15:20:36 -04002117 // Framebuffer detachment is handled by Context, because 0 is a valid
2118 // Framebuffer object, and a pointer to it must be passed from Context
2119 // to State at binding time.
2120
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002121 // [OpenGL ES 2.0.24] section 4.4 page 107:
2122 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2123 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2124
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002125 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002126 {
2127 bindReadFramebuffer(0);
2128 }
2129
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002130 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002131 {
2132 bindDrawFramebuffer(0);
2133 }
2134}
2135
2136void Context::detachRenderbuffer(GLuint renderbuffer)
2137{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002138 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002139}
2140
Jamie Madill57a89722013-07-02 11:57:03 -04002141void Context::detachVertexArray(GLuint vertexArray)
2142{
Jamie Madill77a72f62015-04-14 11:18:32 -04002143 // Vertex array detachment is handled by Context, because 0 is a valid
2144 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002145 // binding time.
2146
Jamie Madill57a89722013-07-02 11:57:03 -04002147 // [OpenGL ES 3.0.2] section 2.10 page 43:
2148 // If a vertex array object that is currently bound is deleted, the binding
2149 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002150 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002151 {
2152 bindVertexArray(0);
2153 }
2154}
2155
Geoff Langc8058452014-02-03 12:04:11 -05002156void Context::detachTransformFeedback(GLuint transformFeedback)
2157{
Corentin Walleza2257da2016-04-19 16:43:12 -04002158 // Transform feedback detachment is handled by Context, because 0 is a valid
2159 // transform feedback, and a pointer to it must be passed from Context to State at
2160 // binding time.
2161
2162 // The OpenGL specification doesn't mention what should happen when the currently bound
2163 // transform feedback object is deleted. Since it is a container object, we treat it like
2164 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002165 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002166 {
2167 bindTransformFeedback(0);
2168 }
Geoff Langc8058452014-02-03 12:04:11 -05002169}
2170
Jamie Madilldc356042013-07-19 16:36:57 -04002171void Context::detachSampler(GLuint sampler)
2172{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002173 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002174}
2175
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002176void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2177{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002178 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002179}
2180
Jamie Madille29d1672013-07-19 16:36:57 -04002181void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2182{
Jamie Madill901b3792016-05-26 09:20:40 -04002183 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002184
2185 Sampler *samplerObject = getSampler(sampler);
2186 ASSERT(samplerObject);
2187
Geoff Lang69cce582015-09-17 13:20:36 -04002188 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002189 switch (pname)
2190 {
Geoff Lang69cce582015-09-17 13:20:36 -04002191 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
2192 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
2193 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
2194 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
2195 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
2196 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
2197 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
2198 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
2199 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
2200 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
2201 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002202 }
Geoff Lang69cce582015-09-17 13:20:36 -04002203 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002204}
2205
2206void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2207{
Jamie Madill901b3792016-05-26 09:20:40 -04002208 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002209
2210 Sampler *samplerObject = getSampler(sampler);
2211 ASSERT(samplerObject);
2212
Geoff Lang69cce582015-09-17 13:20:36 -04002213 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002214 switch (pname)
2215 {
Geoff Lang69cce582015-09-17 13:20:36 -04002216 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
2217 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
2218 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
2219 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
2220 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
2221 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
2222 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
2223 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
2224 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
2225 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
2226 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002227 }
Geoff Lang69cce582015-09-17 13:20:36 -04002228 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002229}
2230
Jamie Madill9675b802013-07-19 16:36:59 -04002231GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
2232{
Jamie Madill901b3792016-05-26 09:20:40 -04002233 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002234
2235 Sampler *samplerObject = getSampler(sampler);
2236 ASSERT(samplerObject);
2237
Geoff Lang69cce582015-09-17 13:20:36 -04002238 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002239 switch (pname)
2240 {
Geoff Lang69cce582015-09-17 13:20:36 -04002241 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
2242 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
2243 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
2244 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
2245 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
2246 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02002247 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
2248 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04002249 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
2250 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
2251 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002252 }
Geoff Lang69cce582015-09-17 13:20:36 -04002253 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002254}
2255
2256GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
2257{
Jamie Madill901b3792016-05-26 09:20:40 -04002258 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002259
2260 Sampler *samplerObject = getSampler(sampler);
2261 ASSERT(samplerObject);
2262
Geoff Lang69cce582015-09-17 13:20:36 -04002263 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002264 switch (pname)
2265 {
Geoff Lang69cce582015-09-17 13:20:36 -04002266 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
2267 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
2268 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
2269 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2270 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2271 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
2272 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2273 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2274 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2275 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2276 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002277 }
Geoff Lang69cce582015-09-17 13:20:36 -04002278 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002279}
2280
Olli Etuahof0fee072016-03-30 15:11:58 +03002281void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2282{
2283 gl::Program *programObject = getProgram(program);
2284 ASSERT(programObject != nullptr);
2285
2286 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2287 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2288}
2289
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002290void Context::initRendererString()
2291{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002292 std::ostringstream rendererString;
2293 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002294 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002295 rendererString << ")";
2296
Geoff Langcec35902014-04-16 10:52:36 -04002297 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002298}
2299
Geoff Langc287ea62016-09-16 14:46:51 -04002300const char *Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002301{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002302 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002303}
2304
Geoff Langcec35902014-04-16 10:52:36 -04002305void Context::initExtensionStrings()
2306{
Geoff Langc287ea62016-09-16 14:46:51 -04002307 for (const auto &extensionString : mExtensions.getStrings())
2308 {
2309 mExtensionStrings.push_back(MakeStaticString(extensionString));
2310 }
Geoff Langcec35902014-04-16 10:52:36 -04002311
Geoff Langc0b9ef42014-07-02 10:02:37 -04002312 std::ostringstream combinedStringStream;
Geoff Langc287ea62016-09-16 14:46:51 -04002313 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(),
2314 std::ostream_iterator<const char *>(combinedStringStream, " "));
2315 mExtensionString = MakeStaticString(combinedStringStream.str());
Geoff Langcec35902014-04-16 10:52:36 -04002316}
2317
Geoff Langc287ea62016-09-16 14:46:51 -04002318const char *Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002319{
2320 return mExtensionString;
2321}
2322
Geoff Langc287ea62016-09-16 14:46:51 -04002323const char *Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002324{
2325 return mExtensionStrings[idx];
2326}
2327
2328size_t Context::getExtensionStringCount() const
2329{
2330 return mExtensionStrings.size();
2331}
2332
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002333void Context::beginTransformFeedback(GLenum primitiveMode)
2334{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002335 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002336 ASSERT(transformFeedback != nullptr);
2337 ASSERT(!transformFeedback->isPaused());
2338
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002339 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002340}
2341
2342bool Context::hasActiveTransformFeedback(GLuint program) const
2343{
2344 for (auto pair : mTransformFeedbackMap)
2345 {
2346 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2347 {
2348 return true;
2349 }
2350 }
2351 return false;
2352}
2353
Geoff Langc287ea62016-09-16 14:46:51 -04002354void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002355{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002356 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002357
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002358 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002359
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002360 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002361
Martin Radev1be913c2016-07-11 17:59:16 +03002362 if (mClientMajorVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002363 {
2364 // Disable ES3+ extensions
2365 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002366 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002367 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002368 }
2369
Martin Radev1be913c2016-07-11 17:59:16 +03002370 if (mClientMajorVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002371 {
2372 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2373 //mExtensions.sRGB = false;
2374 }
2375
Jamie Madill00ed7a12016-05-19 13:13:38 -04002376 // Some extensions are always available because they are implemented in the GL layer.
2377 mExtensions.bindUniformLocation = true;
2378 mExtensions.vertexArrayObject = true;
2379
2380 // Enable the no error extension if the context was created with the flag.
2381 mExtensions.noError = mSkipValidation;
2382
Geoff Lang70d0f492015-12-10 17:45:46 -05002383 // Explicitly enable GL_KHR_debug
2384 mExtensions.debug = true;
2385 mExtensions.maxDebugMessageLength = 1024;
2386 mExtensions.maxDebugLoggedMessages = 1024;
2387 mExtensions.maxDebugGroupStackDepth = 1024;
2388 mExtensions.maxLabelLength = 1024;
2389
Geoff Lang301d1612014-07-09 10:34:37 -04002390 // Apply implementation limits
2391 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002392 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2393 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2394
2395 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002396
Geoff Langc287ea62016-09-16 14:46:51 -04002397 // WebGL compatibility
2398 mExtensions.webglCompatibility = webGLContext;
2399 for (const auto &extensionInfo : GetExtensionInfoMap())
2400 {
2401 // If this context is for WebGL, disable all enableable extensions
2402 if (webGLContext && extensionInfo.second.Enableable)
2403 {
2404 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2405 }
2406 }
2407
2408 // Generate texture caps
2409 updateCaps();
2410}
2411
2412void Context::updateCaps()
2413{
Geoff Lang900013c2014-07-07 11:32:19 -04002414 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002415 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002416
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002417 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002418 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2419 {
2420 GLenum format = i->first;
2421 TextureCaps formatCaps = i->second;
2422
Geoff Lang5d601382014-07-22 15:14:06 -04002423 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002424
Geoff Lang0d8b7242015-09-09 14:56:53 -04002425 // Update the format caps based on the client version and extensions.
2426 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2427 // ES3.
2428 formatCaps.texturable =
Martin Radev1be913c2016-07-11 17:59:16 +03002429 formatCaps.texturable && formatInfo.textureSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002430 formatCaps.renderable =
Martin Radev1be913c2016-07-11 17:59:16 +03002431 formatCaps.renderable && formatInfo.renderSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002432 formatCaps.filterable =
Martin Radev1be913c2016-07-11 17:59:16 +03002433 formatCaps.filterable && formatInfo.filterSupport(mClientMajorVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002434
2435 // OpenGL ES does not support multisampling with integer formats
2436 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002437 {
Geoff Langd87878e2014-09-19 15:42:59 -04002438 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002439 }
Geoff Langd87878e2014-09-19 15:42:59 -04002440
2441 if (formatCaps.texturable && formatInfo.compressed)
2442 {
2443 mCaps.compressedTextureFormats.push_back(format);
2444 }
2445
2446 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002447 }
2448}
2449
Jamie Madill1b94d432015-08-07 13:23:23 -04002450void Context::syncRendererState()
2451{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002452 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2453 mImplementation->syncState(mGLState, dirtyBits);
2454 mGLState.clearDirtyBits();
2455 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002456}
2457
Jamie Madillad9f24e2016-02-12 09:27:24 -05002458void Context::syncRendererState(const State::DirtyBits &bitMask,
2459 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002460{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002461 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2462 mImplementation->syncState(mGLState, dirtyBits);
2463 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002464
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002465 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002466}
Jamie Madillc29968b2016-01-20 11:17:23 -05002467
2468void Context::blitFramebuffer(GLint srcX0,
2469 GLint srcY0,
2470 GLint srcX1,
2471 GLint srcY1,
2472 GLint dstX0,
2473 GLint dstY0,
2474 GLint dstX1,
2475 GLint dstY1,
2476 GLbitfield mask,
2477 GLenum filter)
2478{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002479 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002480 ASSERT(drawFramebuffer);
2481
2482 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2483 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2484
Jamie Madillad9f24e2016-02-12 09:27:24 -05002485 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002486
Jamie Madill8415b5f2016-04-26 13:41:39 -04002487 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002488}
Jamie Madillc29968b2016-01-20 11:17:23 -05002489
2490void Context::clear(GLbitfield mask)
2491{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002492 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002493 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002494}
2495
2496void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2497{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002498 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002499 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2500 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002501}
2502
2503void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2504{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002505 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002506 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2507 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002508}
2509
2510void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2511{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002512 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002513 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2514 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002515}
2516
2517void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2518{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002519 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002520 ASSERT(framebufferObject);
2521
2522 // If a buffer is not present, the clear has no effect
2523 if (framebufferObject->getDepthbuffer() == nullptr &&
2524 framebufferObject->getStencilbuffer() == nullptr)
2525 {
2526 return;
2527 }
2528
Jamie Madillad9f24e2016-02-12 09:27:24 -05002529 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002530 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2531 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002532}
2533
2534void Context::readPixels(GLint x,
2535 GLint y,
2536 GLsizei width,
2537 GLsizei height,
2538 GLenum format,
2539 GLenum type,
2540 GLvoid *pixels)
2541{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002542 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002543
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002544 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002545 ASSERT(framebufferObject);
2546
2547 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002548 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002549}
2550
2551void Context::copyTexImage2D(GLenum target,
2552 GLint level,
2553 GLenum internalformat,
2554 GLint x,
2555 GLint y,
2556 GLsizei width,
2557 GLsizei height,
2558 GLint border)
2559{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002560 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002561 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002562
Jamie Madillc29968b2016-01-20 11:17:23 -05002563 Rectangle sourceArea(x, y, width, height);
2564
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002565 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002566 Texture *texture =
2567 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002568 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002569}
2570
2571void Context::copyTexSubImage2D(GLenum target,
2572 GLint level,
2573 GLint xoffset,
2574 GLint yoffset,
2575 GLint x,
2576 GLint y,
2577 GLsizei width,
2578 GLsizei height)
2579{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002580 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002581 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002582
Jamie Madillc29968b2016-01-20 11:17:23 -05002583 Offset destOffset(xoffset, yoffset, 0);
2584 Rectangle sourceArea(x, y, width, height);
2585
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002586 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002587 Texture *texture =
2588 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002589 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002590}
2591
2592void Context::copyTexSubImage3D(GLenum target,
2593 GLint level,
2594 GLint xoffset,
2595 GLint yoffset,
2596 GLint zoffset,
2597 GLint x,
2598 GLint y,
2599 GLsizei width,
2600 GLsizei height)
2601{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002602 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002603 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002604
Jamie Madillc29968b2016-01-20 11:17:23 -05002605 Offset destOffset(xoffset, yoffset, zoffset);
2606 Rectangle sourceArea(x, y, width, height);
2607
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002608 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002609 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002610 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002611}
2612
2613void Context::framebufferTexture2D(GLenum target,
2614 GLenum attachment,
2615 GLenum textarget,
2616 GLuint texture,
2617 GLint level)
2618{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002619 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002620 ASSERT(framebuffer);
2621
2622 if (texture != 0)
2623 {
2624 Texture *textureObj = getTexture(texture);
2625
2626 ImageIndex index = ImageIndex::MakeInvalid();
2627
2628 if (textarget == GL_TEXTURE_2D)
2629 {
2630 index = ImageIndex::Make2D(level);
2631 }
2632 else
2633 {
2634 ASSERT(IsCubeMapTextureTarget(textarget));
2635 index = ImageIndex::MakeCube(textarget, level);
2636 }
2637
2638 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2639 }
2640 else
2641 {
2642 framebuffer->resetAttachment(attachment);
2643 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002644
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002645 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002646}
2647
2648void Context::framebufferRenderbuffer(GLenum target,
2649 GLenum attachment,
2650 GLenum renderbuffertarget,
2651 GLuint renderbuffer)
2652{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002653 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002654 ASSERT(framebuffer);
2655
2656 if (renderbuffer != 0)
2657 {
2658 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2659 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2660 renderbufferObject);
2661 }
2662 else
2663 {
2664 framebuffer->resetAttachment(attachment);
2665 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002666
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002667 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002668}
2669
2670void Context::framebufferTextureLayer(GLenum target,
2671 GLenum attachment,
2672 GLuint texture,
2673 GLint level,
2674 GLint layer)
2675{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002676 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002677 ASSERT(framebuffer);
2678
2679 if (texture != 0)
2680 {
2681 Texture *textureObject = getTexture(texture);
2682
2683 ImageIndex index = ImageIndex::MakeInvalid();
2684
2685 if (textureObject->getTarget() == GL_TEXTURE_3D)
2686 {
2687 index = ImageIndex::Make3D(level, layer);
2688 }
2689 else
2690 {
2691 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2692 index = ImageIndex::Make2DArray(level, layer);
2693 }
2694
2695 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2696 }
2697 else
2698 {
2699 framebuffer->resetAttachment(attachment);
2700 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002701
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002702 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002703}
2704
2705void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2706{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002707 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002708 ASSERT(framebuffer);
2709 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002710 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002711}
2712
2713void Context::readBuffer(GLenum mode)
2714{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002715 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002716 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002717 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002718}
2719
2720void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2721{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002722 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002723 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002724
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002725 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002726 ASSERT(framebuffer);
2727
2728 // The specification isn't clear what should be done when the framebuffer isn't complete.
2729 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002730 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002731}
2732
2733void Context::invalidateFramebuffer(GLenum target,
2734 GLsizei numAttachments,
2735 const GLenum *attachments)
2736{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002737 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002738 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002739
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002740 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002741 ASSERT(framebuffer);
2742
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002743 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002744 {
Jamie Madill437fa652016-05-03 15:13:24 -04002745 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002746 }
Jamie Madill437fa652016-05-03 15:13:24 -04002747
2748 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002749}
2750
2751void Context::invalidateSubFramebuffer(GLenum target,
2752 GLsizei numAttachments,
2753 const GLenum *attachments,
2754 GLint x,
2755 GLint y,
2756 GLsizei width,
2757 GLsizei height)
2758{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002759 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002760 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002761
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002762 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002763 ASSERT(framebuffer);
2764
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002765 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002766 {
Jamie Madill437fa652016-05-03 15:13:24 -04002767 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002768 }
Jamie Madill437fa652016-05-03 15:13:24 -04002769
2770 Rectangle area(x, y, width, height);
2771 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002772}
2773
Jamie Madill73a84962016-02-12 09:27:23 -05002774void Context::texImage2D(GLenum target,
2775 GLint level,
2776 GLint internalformat,
2777 GLsizei width,
2778 GLsizei height,
2779 GLint border,
2780 GLenum format,
2781 GLenum type,
2782 const GLvoid *pixels)
2783{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002784 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002785
2786 Extents size(width, height, 1);
2787 Texture *texture =
2788 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002789 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002790 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002791}
2792
2793void Context::texImage3D(GLenum target,
2794 GLint level,
2795 GLint internalformat,
2796 GLsizei width,
2797 GLsizei height,
2798 GLsizei depth,
2799 GLint border,
2800 GLenum format,
2801 GLenum type,
2802 const GLvoid *pixels)
2803{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002804 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002805
2806 Extents size(width, height, depth);
2807 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002808 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002809 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002810}
2811
2812void Context::texSubImage2D(GLenum target,
2813 GLint level,
2814 GLint xoffset,
2815 GLint yoffset,
2816 GLsizei width,
2817 GLsizei height,
2818 GLenum format,
2819 GLenum type,
2820 const GLvoid *pixels)
2821{
2822 // Zero sized uploads are valid but no-ops
2823 if (width == 0 || height == 0)
2824 {
2825 return;
2826 }
2827
Jamie Madillad9f24e2016-02-12 09:27:24 -05002828 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002829
2830 Box area(xoffset, yoffset, 0, width, height, 1);
2831 Texture *texture =
2832 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002833 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002834 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002835}
2836
2837void Context::texSubImage3D(GLenum target,
2838 GLint level,
2839 GLint xoffset,
2840 GLint yoffset,
2841 GLint zoffset,
2842 GLsizei width,
2843 GLsizei height,
2844 GLsizei depth,
2845 GLenum format,
2846 GLenum type,
2847 const GLvoid *pixels)
2848{
2849 // Zero sized uploads are valid but no-ops
2850 if (width == 0 || height == 0 || depth == 0)
2851 {
2852 return;
2853 }
2854
Jamie Madillad9f24e2016-02-12 09:27:24 -05002855 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002856
2857 Box area(xoffset, yoffset, zoffset, width, height, depth);
2858 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002859 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002860 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002861}
2862
2863void Context::compressedTexImage2D(GLenum target,
2864 GLint level,
2865 GLenum internalformat,
2866 GLsizei width,
2867 GLsizei height,
2868 GLint border,
2869 GLsizei imageSize,
2870 const GLvoid *data)
2871{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002872 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002873
2874 Extents size(width, height, 1);
2875 Texture *texture =
2876 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002877 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2878 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002879 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002880}
2881
2882void Context::compressedTexImage3D(GLenum target,
2883 GLint level,
2884 GLenum internalformat,
2885 GLsizei width,
2886 GLsizei height,
2887 GLsizei depth,
2888 GLint border,
2889 GLsizei imageSize,
2890 const GLvoid *data)
2891{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002892 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002893
2894 Extents size(width, height, depth);
2895 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002896 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2897 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002898 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002899}
2900
2901void Context::compressedTexSubImage2D(GLenum target,
2902 GLint level,
2903 GLint xoffset,
2904 GLint yoffset,
2905 GLsizei width,
2906 GLsizei height,
2907 GLenum format,
2908 GLsizei imageSize,
2909 const GLvoid *data)
2910{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002911 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002912
2913 Box area(xoffset, yoffset, 0, width, height, 1);
2914 Texture *texture =
2915 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002916 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2917 format, imageSize,
2918 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002919}
2920
2921void Context::compressedTexSubImage3D(GLenum target,
2922 GLint level,
2923 GLint xoffset,
2924 GLint yoffset,
2925 GLint zoffset,
2926 GLsizei width,
2927 GLsizei height,
2928 GLsizei depth,
2929 GLenum format,
2930 GLsizei imageSize,
2931 const GLvoid *data)
2932{
2933 // Zero sized uploads are valid but no-ops
2934 if (width == 0 || height == 0)
2935 {
2936 return;
2937 }
2938
Jamie Madillad9f24e2016-02-12 09:27:24 -05002939 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002940
2941 Box area(xoffset, yoffset, zoffset, width, height, depth);
2942 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002943 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2944 format, imageSize,
2945 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002946}
2947
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002948void Context::generateMipmap(GLenum target)
2949{
2950 Texture *texture = getTargetTexture(target);
2951 handleError(texture->generateMipmap());
2952}
2953
Geoff Langc287ea62016-09-16 14:46:51 -04002954GLboolean Context::enableExtension(const char *name)
2955{
2956 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2957 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2958 const auto &extension = extensionInfos.at(name);
2959 ASSERT(extension.Enableable);
2960
2961 if (mExtensions.*(extension.ExtensionsMember))
2962 {
2963 // Extension already enabled
2964 return GL_TRUE;
2965 }
2966
2967 const auto &nativeExtensions = mImplementation->getNativeExtensions();
2968 if (!(nativeExtensions.*(extension.ExtensionsMember)))
2969 {
2970 // Underlying implementation does not support this valid extension
2971 return GL_FALSE;
2972 }
2973
2974 mExtensions.*(extension.ExtensionsMember) = true;
2975 updateCaps();
2976 initExtensionStrings();
2977 return GL_TRUE;
2978}
2979
Geoff Lang97073d12016-04-20 10:42:34 -07002980void Context::copyTextureCHROMIUM(GLuint sourceId,
2981 GLuint destId,
2982 GLint internalFormat,
2983 GLenum destType,
2984 GLboolean unpackFlipY,
2985 GLboolean unpackPremultiplyAlpha,
2986 GLboolean unpackUnmultiplyAlpha)
2987{
2988 syncStateForTexImage();
2989
2990 gl::Texture *sourceTexture = getTexture(sourceId);
2991 gl::Texture *destTexture = getTexture(destId);
2992 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
2993 unpackPremultiplyAlpha == GL_TRUE,
2994 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
2995}
2996
2997void Context::copySubTextureCHROMIUM(GLuint sourceId,
2998 GLuint destId,
2999 GLint xoffset,
3000 GLint yoffset,
3001 GLint x,
3002 GLint y,
3003 GLsizei width,
3004 GLsizei height,
3005 GLboolean unpackFlipY,
3006 GLboolean unpackPremultiplyAlpha,
3007 GLboolean unpackUnmultiplyAlpha)
3008{
3009 // Zero sized copies are valid but no-ops
3010 if (width == 0 || height == 0)
3011 {
3012 return;
3013 }
3014
3015 syncStateForTexImage();
3016
3017 gl::Texture *sourceTexture = getTexture(sourceId);
3018 gl::Texture *destTexture = getTexture(destId);
3019 Offset offset(xoffset, yoffset, 0);
3020 Rectangle area(x, y, width, height);
3021 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3022 unpackPremultiplyAlpha == GL_TRUE,
3023 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3024}
3025
Olli Etuaho4f667482016-03-30 15:56:35 +03003026void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
3027{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003028 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003029 ASSERT(buffer);
3030
3031 if (!buffer->isMapped())
3032 {
3033 *params = nullptr;
3034 }
3035 else
3036 {
3037 *params = buffer->getMapPointer();
3038 }
3039}
3040
3041GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3042{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003043 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003044 ASSERT(buffer);
3045
3046 Error error = buffer->map(access);
3047 if (error.isError())
3048 {
Jamie Madill437fa652016-05-03 15:13:24 -04003049 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003050 return nullptr;
3051 }
3052
3053 return buffer->getMapPointer();
3054}
3055
3056GLboolean Context::unmapBuffer(GLenum target)
3057{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003058 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003059 ASSERT(buffer);
3060
3061 GLboolean result;
3062 Error error = buffer->unmap(&result);
3063 if (error.isError())
3064 {
Jamie Madill437fa652016-05-03 15:13:24 -04003065 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003066 return GL_FALSE;
3067 }
3068
3069 return result;
3070}
3071
3072GLvoid *Context::mapBufferRange(GLenum target,
3073 GLintptr offset,
3074 GLsizeiptr length,
3075 GLbitfield access)
3076{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003077 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003078 ASSERT(buffer);
3079
3080 Error error = buffer->mapRange(offset, length, access);
3081 if (error.isError())
3082 {
Jamie Madill437fa652016-05-03 15:13:24 -04003083 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003084 return nullptr;
3085 }
3086
3087 return buffer->getMapPointer();
3088}
3089
3090void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3091{
3092 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3093}
3094
Jamie Madillad9f24e2016-02-12 09:27:24 -05003095void Context::syncStateForReadPixels()
3096{
3097 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3098}
3099
3100void Context::syncStateForTexImage()
3101{
3102 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3103}
3104
3105void Context::syncStateForClear()
3106{
3107 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3108}
3109
3110void Context::syncStateForBlit()
3111{
3112 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3113}
3114
Jamie Madillc20ab272016-06-09 07:20:46 -07003115void Context::activeTexture(GLenum texture)
3116{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003117 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003118}
3119
3120void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3121{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003122 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003123}
3124
3125void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3126{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003127 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003128}
3129
3130void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3131{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003132 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003133}
3134
3135void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3136{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003137 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003138}
3139
3140void Context::clearDepthf(GLclampf depth)
3141{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003142 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003143}
3144
3145void Context::clearStencil(GLint s)
3146{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003147 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003148}
3149
3150void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3151{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003152 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003153}
3154
3155void Context::cullFace(GLenum mode)
3156{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003157 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003158}
3159
3160void Context::depthFunc(GLenum func)
3161{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003162 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003163}
3164
3165void Context::depthMask(GLboolean flag)
3166{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003167 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003168}
3169
3170void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3171{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003172 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003173}
3174
3175void Context::disable(GLenum cap)
3176{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003177 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003178}
3179
3180void Context::disableVertexAttribArray(GLuint index)
3181{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003182 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003183}
3184
3185void Context::enable(GLenum cap)
3186{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003187 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003188}
3189
3190void Context::enableVertexAttribArray(GLuint index)
3191{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003192 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003193}
3194
3195void Context::frontFace(GLenum mode)
3196{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003197 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003198}
3199
3200void Context::hint(GLenum target, GLenum mode)
3201{
3202 switch (target)
3203 {
3204 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003205 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003206 break;
3207
3208 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003209 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003210 break;
3211
3212 default:
3213 UNREACHABLE();
3214 return;
3215 }
3216}
3217
3218void Context::lineWidth(GLfloat width)
3219{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003220 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003221}
3222
3223void Context::pixelStorei(GLenum pname, GLint param)
3224{
3225 switch (pname)
3226 {
3227 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003228 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003229 break;
3230
3231 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003232 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003233 break;
3234
3235 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003236 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003237 break;
3238
3239 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003240 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003241 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003242 break;
3243
3244 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003245 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003246 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003247 break;
3248
3249 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003250 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003251 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003252 break;
3253
3254 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003255 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003256 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003257 break;
3258
3259 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003260 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003261 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003262 break;
3263
3264 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003265 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003266 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003267 break;
3268
3269 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003270 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003271 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003272 break;
3273
3274 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003275 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003276 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003277 break;
3278
3279 default:
3280 UNREACHABLE();
3281 return;
3282 }
3283}
3284
3285void Context::polygonOffset(GLfloat factor, GLfloat units)
3286{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003287 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003288}
3289
3290void Context::sampleCoverage(GLclampf value, GLboolean invert)
3291{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003292 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003293}
3294
3295void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3296{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003297 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003298}
3299
3300void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3301{
3302 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3303 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003304 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003305 }
3306
3307 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3308 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003309 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003310 }
3311}
3312
3313void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3314{
3315 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3316 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003317 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003318 }
3319
3320 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3321 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003322 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003323 }
3324}
3325
3326void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3327{
3328 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3329 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003330 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003331 }
3332
3333 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3334 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003335 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003336 }
3337}
3338
3339void Context::vertexAttrib1f(GLuint index, GLfloat x)
3340{
3341 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003342 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003343}
3344
3345void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3346{
3347 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003348 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003349}
3350
3351void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3352{
3353 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003355}
3356
3357void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3358{
3359 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003360 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003361}
3362
3363void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3364{
3365 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003366 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003367}
3368
3369void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3370{
3371 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003372 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003373}
3374
3375void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3376{
3377 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003378 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003379}
3380
3381void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3382{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003383 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003384}
3385
3386void Context::vertexAttribPointer(GLuint index,
3387 GLint size,
3388 GLenum type,
3389 GLboolean normalized,
3390 GLsizei stride,
3391 const GLvoid *ptr)
3392{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003393 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3394 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003395}
3396
3397void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3398{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003400}
3401
3402void Context::vertexAttribIPointer(GLuint index,
3403 GLint size,
3404 GLenum type,
3405 GLsizei stride,
3406 const GLvoid *pointer)
3407{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003408 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3409 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003410}
3411
3412void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3413{
3414 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003415 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003416}
3417
3418void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3419{
3420 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003421 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003422}
3423
3424void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3425{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003426 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003427}
3428
3429void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3430{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003431 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003432}
3433
3434void Context::debugMessageControl(GLenum source,
3435 GLenum type,
3436 GLenum severity,
3437 GLsizei count,
3438 const GLuint *ids,
3439 GLboolean enabled)
3440{
3441 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003442 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3443 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003444}
3445
3446void Context::debugMessageInsert(GLenum source,
3447 GLenum type,
3448 GLuint id,
3449 GLenum severity,
3450 GLsizei length,
3451 const GLchar *buf)
3452{
3453 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003454 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003455}
3456
3457void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3458{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003459 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003460}
3461
3462GLuint Context::getDebugMessageLog(GLuint count,
3463 GLsizei bufSize,
3464 GLenum *sources,
3465 GLenum *types,
3466 GLuint *ids,
3467 GLenum *severities,
3468 GLsizei *lengths,
3469 GLchar *messageLog)
3470{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003471 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3472 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003473}
3474
3475void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3476{
3477 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003478 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003479}
3480
3481void Context::popDebugGroup()
3482{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003484}
3485
Jamie Madill29639852016-09-02 15:00:09 -04003486void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3487{
3488 Buffer *buffer = mGLState.getTargetBuffer(target);
3489 ASSERT(buffer);
3490 handleError(buffer->bufferData(target, data, size, usage));
3491}
3492
3493void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3494{
3495 if (data == nullptr)
3496 {
3497 return;
3498 }
3499
3500 Buffer *buffer = mGLState.getTargetBuffer(target);
3501 ASSERT(buffer);
3502 handleError(buffer->bufferSubData(target, data, size, offset));
3503}
3504
Jamie Madillc29968b2016-01-20 11:17:23 -05003505} // namespace gl