blob: b84ba00e0e822e360fefe82dd6e7bd90349eb8b8 [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 Madill231c7f52017-04-26 13:45:37 -040012#include <string.h>
Jamie Madillb9293972015-02-19 11:07:54 -050013#include <iterator>
14#include <sstream>
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 Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Jamie Madill948bbe52017-06-01 13:10:42 -040023#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Fence.h"
25#include "libANGLE/Framebuffer.h"
26#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070037#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040038#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030039#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040040#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040041#include "libANGLE/renderer/ContextImpl.h"
42#include "libANGLE/renderer/EGLImplFactory.h"
43#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Jamie Madillb6664922017-07-25 12:55:04 -040048#define ANGLE_HANDLE_ERR(X) \
49 handleError(X); \
50 return;
51#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR);
52
Ian Ewell3ffd78b2016-01-22 16:09:42 -050053template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050054std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030055 GLsizei numPaths,
56 const void *paths,
57 GLuint pathBase)
58{
59 std::vector<gl::Path *> ret;
60 ret.reserve(numPaths);
61
62 const auto *nameArray = static_cast<const T *>(paths);
63
64 for (GLsizei i = 0; i < numPaths; ++i)
65 {
66 const GLuint pathName = nameArray[i] + pathBase;
67
68 ret.push_back(resourceManager.getPath(pathName));
69 }
70
71 return ret;
72}
73
Geoff Lang4ddf5af2016-12-01 14:30:44 -050074std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030075 GLsizei numPaths,
76 GLenum pathNameType,
77 const void *paths,
78 GLuint pathBase)
79{
80 switch (pathNameType)
81 {
82 case GL_UNSIGNED_BYTE:
83 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_BYTE:
86 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_SHORT:
89 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_SHORT:
92 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
93
94 case GL_UNSIGNED_INT:
95 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
96
97 case GL_INT:
98 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
99 }
100
101 UNREACHABLE();
102 return std::vector<gl::Path *>();
103}
104
105template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400106gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500107{
Geoff Lang2186c382016-10-14 10:54:54 -0400108 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109
110 switch (pname)
111 {
112 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400113 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500114 case GL_QUERY_RESULT_AVAILABLE_EXT:
115 {
116 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400117 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500118 if (!error.isError())
119 {
Geoff Lang2186c382016-10-14 10:54:54 -0400120 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500121 }
122 return error;
123 }
124 default:
125 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500126 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500127 }
128}
129
Geoff Langf6db0982015-08-25 13:04:00 -0400130void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
131{
Geoff Lang1a683462015-09-29 15:09:59 -0400132 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400133 {
134 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
135 tfBufferIndex++)
136 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400137 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400138 transformFeedback->getIndexedBuffer(tfBufferIndex);
139 if (buffer.get() != nullptr)
140 {
141 buffer->onTransformFeedback();
142 }
143 }
144 }
145}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146
147// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500149{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151}
152
Martin Radev1be913c2016-07-11 17:59:16 +0300153EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
154{
155 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
156}
157
Geoff Langeb66a6e2016-10-31 13:06:12 -0400158gl::Version GetClientVersion(const egl::AttributeMap &attribs)
159{
160 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
161}
162
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500163GLenum GetResetStrategy(const egl::AttributeMap &attribs)
164{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400165 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
166 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500167 switch (attrib)
168 {
169 case EGL_NO_RESET_NOTIFICATION:
170 return GL_NO_RESET_NOTIFICATION_EXT;
171 case EGL_LOSE_CONTEXT_ON_RESET:
172 return GL_LOSE_CONTEXT_ON_RESET_EXT;
173 default:
174 UNREACHABLE();
175 return GL_NONE;
176 }
177}
178
179bool GetRobustAccess(const egl::AttributeMap &attribs)
180{
Geoff Lang077f20a2016-11-01 10:08:02 -0400181 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
182 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
183 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184}
185
186bool GetDebug(const egl::AttributeMap &attribs)
187{
Geoff Lang077f20a2016-11-01 10:08:02 -0400188 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
189 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500190}
191
192bool GetNoError(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langc287ea62016-09-16 14:46:51 -0400197bool GetWebGLContext(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
200}
201
Geoff Langf41a7152016-09-19 15:11:17 -0400202bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
205}
206
Geoff Langfeb8c682017-02-13 16:07:35 -0500207bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
208{
209 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
210}
211
Martin Radev9d901792016-07-15 15:58:58 +0300212std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
213{
214 std::string labelName;
215 if (label != nullptr)
216 {
217 size_t labelLength = length < 0 ? strlen(label) : length;
218 labelName = std::string(label, labelLength);
219 }
220 return labelName;
221}
222
223void GetObjectLabelBase(const std::string &objectLabel,
224 GLsizei bufSize,
225 GLsizei *length,
226 GLchar *label)
227{
228 size_t writeLength = objectLabel.length();
229 if (label != nullptr && bufSize > 0)
230 {
231 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
232 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
233 label[writeLength] = '\0';
234 }
235
236 if (length != nullptr)
237 {
238 *length = static_cast<GLsizei>(writeLength);
239 }
240}
241
Geoff Langf6db0982015-08-25 13:04:00 -0400242} // anonymous namespace
243
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000244namespace gl
245{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000246
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400247Context::Context(rx::EGLImplFactory *implFactory,
248 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400249 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500250 TextureManager *shareTextures,
Jamie Madill32447362017-06-28 14:53:52 -0400251 MemoryProgramCache *memoryProgramCache,
Corentin Wallezc295e512017-01-27 17:47:50 -0500252 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400253 const egl::DisplayExtensions &displayExtensions,
254 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300255
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500256 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500257 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500258 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700259 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500260 mCaps,
261 mTextureCaps,
262 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500263 mLimitations,
264 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700265 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400266 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400267 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500268 mClientType(EGL_OPENGL_ES_API),
269 mHasBeenCurrent(false),
270 mContextLost(false),
271 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700272 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500273 mResetStrategy(GetResetStrategy(attribs)),
274 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400275 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
276 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500277 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500278 mWebGLContext(GetWebGLContext(attribs)),
Jamie Madill32447362017-06-28 14:53:52 -0400279 mMemoryProgramCache(memoryProgramCache),
Jamie Madillb3f26b92017-07-19 15:07:41 -0400280 mScratchBuffer(1000u),
281 mZeroFilledBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282{
Geoff Lang077f20a2016-11-01 10:08:02 -0400283 if (mRobustAccess)
284 {
285 UNIMPLEMENTED();
286 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000287
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500288 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700289 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400290
Jamie Madill4928b7c2017-06-20 12:57:39 -0400291 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400292 GetClientArraysEnabled(attribs), robustResourceInit,
293 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100294
Shannon Woods53a94a82014-06-24 15:20:36 -0400295 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400296
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000297 // [OpenGL ES 2.0.24] section 3.7 page 83:
298 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
299 // and cube map texture state vectors respectively associated with them.
300 // In order that access to these initial textures not be lost, they are treated as texture
301 // objects all of whose names are 0.
302
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400304 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500305
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400307 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308
Geoff Langeb66a6e2016-10-31 13:06:12 -0400309 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400310 {
311 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400312 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400313 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400314
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400315 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400316 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400317 }
Geoff Lang3b573612016-10-31 14:08:10 -0400318 if (getClientVersion() >= Version(3, 1))
319 {
320 Texture *zeroTexture2DMultisample =
321 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400322 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800323
324 bindGenericAtomicCounterBuffer(0);
325 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
326 {
327 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
328 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800329
330 bindGenericShaderStorageBuffer(0);
331 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
332 {
333 bindIndexedShaderStorageBuffer(0, i, 0, 0);
334 }
Geoff Lang3b573612016-10-31 14:08:10 -0400335 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000336
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400337 if (mExtensions.textureRectangle)
338 {
339 Texture *zeroTextureRectangle =
340 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
341 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
342 }
343
Ian Ewellbda75592016-04-18 17:25:54 -0400344 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
345 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400346 Texture *zeroTextureExternal =
347 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400348 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400349 }
350
Jamie Madill4928b7c2017-06-20 12:57:39 -0400351 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500352
Jamie Madill57a89722013-07-02 11:57:03 -0400353 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000354 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800355 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000356 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400357
Jamie Madill01a80ee2016-11-07 12:06:18 -0500358 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000359
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000360 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500361 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000362 {
363 bindIndexedUniformBuffer(0, i, 0, -1);
364 }
365
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000366 bindCopyReadBuffer(0);
367 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000368 bindPixelPackBuffer(0);
369 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000370
Geoff Langeb66a6e2016-10-31 13:06:12 -0400371 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400372 {
373 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
374 // In the initial state, a default transform feedback object is bound and treated as
375 // a transform feedback object with a name of zero. That object is bound any time
376 // BindTransformFeedback is called with id of zero
Jamie Madillf0dcb8b2017-08-26 19:05:13 -0400377 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Geoff Lang1a683462015-09-29 15:09:59 -0400378 }
Geoff Langc8058452014-02-03 12:04:11 -0500379
Jamie Madillad9f24e2016-02-12 09:27:24 -0500380 // Initialize dirty bit masks
381 // TODO(jmadill): additional ES3 state
382 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
383 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
384 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
385 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
386 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
387 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400388 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500389 // No dirty objects.
390
391 // Readpixels uses the pack state and read FBO
392 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
393 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
394 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
395 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
396 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400397 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500398 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
399
400 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
401 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
402 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
403 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
404 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
405 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
406 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
407 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
408 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
409 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
410 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
411 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
412
413 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
414 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700415 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500416 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
417 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400418
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400419 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420}
421
Jamie Madill4928b7c2017-06-20 12:57:39 -0400422egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423{
Corentin Wallez80b24112015-08-25 16:41:57 -0400424 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000425 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400426 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400428 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429
Corentin Wallez80b24112015-08-25 16:41:57 -0400430 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400432 if (query.second != nullptr)
433 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400434 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400435 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000436 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400437 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438
Corentin Wallez80b24112015-08-25 16:41:57 -0400439 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400440 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400441 if (vertexArray.second)
442 {
443 vertexArray.second->onDestroy(this);
444 }
Jamie Madill57a89722013-07-02 11:57:03 -0400445 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400446 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400447
Corentin Wallez80b24112015-08-25 16:41:57 -0400448 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500449 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500450 if (transformFeedback.second != nullptr)
451 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500452 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500453 }
Geoff Langc8058452014-02-03 12:04:11 -0500454 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400455 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500456
Jamie Madilldedd7b92014-11-05 16:30:36 -0500457 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400458 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400459 zeroTexture.second->onDestroy(this);
460 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400461 }
462 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463
Corentin Wallezccab69d2017-01-27 16:57:15 -0500464 SafeDelete(mSurfacelessFramebuffer);
465
Jamie Madill4928b7c2017-06-20 12:57:39 -0400466 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400467 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500468
Jamie Madill4928b7c2017-06-20 12:57:39 -0400469 mGLState.reset(this);
470
Jamie Madill6c1f6712017-02-14 19:08:04 -0500471 mState.mBuffers->release(this);
472 mState.mShaderPrograms->release(this);
473 mState.mTextures->release(this);
474 mState.mRenderbuffers->release(this);
475 mState.mSamplers->release(this);
Jamie Madill70b5bb02017-08-28 13:32:37 -0400476 mState.mSyncs->release(this);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500477 mState.mPaths->release(this);
478 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400479
480 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000481}
482
Jamie Madill70ee0f62017-02-06 16:04:20 -0500483Context::~Context()
484{
485}
486
Jamie Madill4928b7c2017-06-20 12:57:39 -0400487egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488{
Jamie Madill61e16b42017-06-19 11:13:23 -0400489 mCurrentDisplay = display;
490
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000491 if (!mHasBeenCurrent)
492 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500494 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400495 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000496
Corentin Wallezc295e512017-01-27 17:47:50 -0500497 int width = 0;
498 int height = 0;
499 if (surface != nullptr)
500 {
501 width = surface->getWidth();
502 height = surface->getHeight();
503 }
504
505 mGLState.setViewportParams(0, 0, width, height);
506 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000507
508 mHasBeenCurrent = true;
509 }
510
Jamie Madill1b94d432015-08-07 13:23:23 -0400511 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700512 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400513
Jamie Madill4928b7c2017-06-20 12:57:39 -0400514 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500515
516 Framebuffer *newDefault = nullptr;
517 if (surface != nullptr)
518 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400519 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500520 mCurrentSurface = surface;
521 newDefault = surface->getDefaultFramebuffer();
522 }
523 else
524 {
525 if (mSurfacelessFramebuffer == nullptr)
526 {
527 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
528 }
529
530 newDefault = mSurfacelessFramebuffer;
531 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000532
Corentin Wallez37c39792015-08-20 14:19:46 -0400533 // Update default framebuffer, the binding of the previous default
534 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400535 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700536 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400537 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700538 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400539 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700540 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400541 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700542 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400543 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500544 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400545 }
Ian Ewell292f0052016-02-04 10:37:32 -0500546
547 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400548 mImplementation->onMakeCurrent(this);
549 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000550}
551
Jamie Madill4928b7c2017-06-20 12:57:39 -0400552egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400553{
Corentin Wallez37c39792015-08-20 14:19:46 -0400554 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500555 Framebuffer *currentDefault = nullptr;
556 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400557 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500558 currentDefault = mCurrentSurface->getDefaultFramebuffer();
559 }
560 else if (mSurfacelessFramebuffer != nullptr)
561 {
562 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400563 }
564
Corentin Wallezc295e512017-01-27 17:47:50 -0500565 if (mGLState.getReadFramebuffer() == currentDefault)
566 {
567 mGLState.setReadFramebufferBinding(nullptr);
568 }
569 if (mGLState.getDrawFramebuffer() == currentDefault)
570 {
571 mGLState.setDrawFramebufferBinding(nullptr);
572 }
573 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
574
575 if (mCurrentSurface)
576 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400577 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500578 mCurrentSurface = nullptr;
579 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400580
581 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400582}
583
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000584GLuint Context::createBuffer()
585{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500586 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587}
588
589GLuint Context::createProgram()
590{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500591 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592}
593
594GLuint Context::createShader(GLenum type)
595{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500596 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597}
598
599GLuint Context::createTexture()
600{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500601 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000602}
603
604GLuint Context::createRenderbuffer()
605{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500606 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000607}
608
Sami Väisänene45e53b2016-05-25 10:36:04 +0300609GLuint Context::createPaths(GLsizei range)
610{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500611 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300612 if (resultOrError.isError())
613 {
614 handleError(resultOrError.getError());
615 return 0;
616 }
617 return resultOrError.getResult();
618}
619
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620// Returns an unused framebuffer name
621GLuint Context::createFramebuffer()
622{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500623 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000624}
625
Jamie Madill33dc8432013-07-26 11:55:05 -0400626GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000627{
Jamie Madill33dc8432013-07-26 11:55:05 -0400628 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400629 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630 return handle;
631}
632
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633void Context::deleteBuffer(GLuint buffer)
634{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500635 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000636 {
637 detachBuffer(buffer);
638 }
Jamie Madill893ab082014-05-16 16:56:10 -0400639
Jamie Madill6c1f6712017-02-14 19:08:04 -0500640 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641}
642
643void Context::deleteShader(GLuint shader)
644{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500645 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000646}
647
648void Context::deleteProgram(GLuint program)
649{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500650 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651}
652
653void Context::deleteTexture(GLuint texture)
654{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500655 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656 {
657 detachTexture(texture);
658 }
659
Jamie Madill6c1f6712017-02-14 19:08:04 -0500660 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000661}
662
663void Context::deleteRenderbuffer(GLuint renderbuffer)
664{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500665 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000666 {
667 detachRenderbuffer(renderbuffer);
668 }
Jamie Madill893ab082014-05-16 16:56:10 -0400669
Jamie Madill6c1f6712017-02-14 19:08:04 -0500670 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000671}
672
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400673void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400674{
675 // The spec specifies the underlying Fence object is not deleted until all current
676 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
677 // and since our API is currently designed for being called from a single thread, we can delete
678 // the fence immediately.
Jamie Madill70b5bb02017-08-28 13:32:37 -0400679 mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400680}
681
Sami Väisänene45e53b2016-05-25 10:36:04 +0300682void Context::deletePaths(GLuint first, GLsizei range)
683{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500684 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300685}
686
687bool Context::hasPathData(GLuint path) const
688{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500689 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300690 if (pathObj == nullptr)
691 return false;
692
693 return pathObj->hasPathData();
694}
695
696bool Context::hasPath(GLuint path) const
697{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500698 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300699}
700
701void Context::setPathCommands(GLuint path,
702 GLsizei numCommands,
703 const GLubyte *commands,
704 GLsizei numCoords,
705 GLenum coordType,
706 const void *coords)
707{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500708 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300709
710 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
711}
712
713void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
714{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500715 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300716
717 switch (pname)
718 {
719 case GL_PATH_STROKE_WIDTH_CHROMIUM:
720 pathObj->setStrokeWidth(value);
721 break;
722 case GL_PATH_END_CAPS_CHROMIUM:
723 pathObj->setEndCaps(static_cast<GLenum>(value));
724 break;
725 case GL_PATH_JOIN_STYLE_CHROMIUM:
726 pathObj->setJoinStyle(static_cast<GLenum>(value));
727 break;
728 case GL_PATH_MITER_LIMIT_CHROMIUM:
729 pathObj->setMiterLimit(value);
730 break;
731 case GL_PATH_STROKE_BOUND_CHROMIUM:
732 pathObj->setStrokeBound(value);
733 break;
734 default:
735 UNREACHABLE();
736 break;
737 }
738}
739
740void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
741{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500742 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300743
744 switch (pname)
745 {
746 case GL_PATH_STROKE_WIDTH_CHROMIUM:
747 *value = pathObj->getStrokeWidth();
748 break;
749 case GL_PATH_END_CAPS_CHROMIUM:
750 *value = static_cast<GLfloat>(pathObj->getEndCaps());
751 break;
752 case GL_PATH_JOIN_STYLE_CHROMIUM:
753 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
754 break;
755 case GL_PATH_MITER_LIMIT_CHROMIUM:
756 *value = pathObj->getMiterLimit();
757 break;
758 case GL_PATH_STROKE_BOUND_CHROMIUM:
759 *value = pathObj->getStrokeBound();
760 break;
761 default:
762 UNREACHABLE();
763 break;
764 }
765}
766
767void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
768{
769 mGLState.setPathStencilFunc(func, ref, mask);
770}
771
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000772void Context::deleteFramebuffer(GLuint framebuffer)
773{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500774 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000775 {
776 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000777 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500778
Jamie Madill6c1f6712017-02-14 19:08:04 -0500779 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000780}
781
Jamie Madill33dc8432013-07-26 11:55:05 -0400782void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000783{
Jamie Madill96a483b2017-06-27 16:49:21 -0400784 FenceNV *fenceObject = nullptr;
785 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000786 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400787 mFenceNVHandleAllocator.release(fence);
788 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000789 }
790}
791
Geoff Lang70d0f492015-12-10 17:45:46 -0500792Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500794 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795}
796
Jamie Madill570f7c82014-07-03 10:38:54 -0400797Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500799 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800}
801
Geoff Lang70d0f492015-12-10 17:45:46 -0500802Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000803{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500804 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805}
806
Jamie Madill70b5bb02017-08-28 13:32:37 -0400807Sync *Context::getSync(GLsync handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400808{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400809 return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400810}
811
Jamie Madill57a89722013-07-02 11:57:03 -0400812VertexArray *Context::getVertexArray(GLuint handle) const
813{
Jamie Madill96a483b2017-06-27 16:49:21 -0400814 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400815}
816
Jamie Madilldc356042013-07-19 16:36:57 -0400817Sampler *Context::getSampler(GLuint handle) const
818{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500819 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400820}
821
Geoff Langc8058452014-02-03 12:04:11 -0500822TransformFeedback *Context::getTransformFeedback(GLuint handle) const
823{
Jamie Madill96a483b2017-06-27 16:49:21 -0400824 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500825}
826
Geoff Lang70d0f492015-12-10 17:45:46 -0500827LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
828{
829 switch (identifier)
830 {
831 case GL_BUFFER:
832 return getBuffer(name);
833 case GL_SHADER:
834 return getShader(name);
835 case GL_PROGRAM:
836 return getProgram(name);
837 case GL_VERTEX_ARRAY:
838 return getVertexArray(name);
839 case GL_QUERY:
840 return getQuery(name);
841 case GL_TRANSFORM_FEEDBACK:
842 return getTransformFeedback(name);
843 case GL_SAMPLER:
844 return getSampler(name);
845 case GL_TEXTURE:
846 return getTexture(name);
847 case GL_RENDERBUFFER:
848 return getRenderbuffer(name);
849 case GL_FRAMEBUFFER:
850 return getFramebuffer(name);
851 default:
852 UNREACHABLE();
853 return nullptr;
854 }
855}
856
857LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
858{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400859 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
Geoff Lang70d0f492015-12-10 17:45:46 -0500860}
861
Martin Radev9d901792016-07-15 15:58:58 +0300862void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
863{
864 LabeledObject *object = getLabeledObject(identifier, name);
865 ASSERT(object != nullptr);
866
867 std::string labelName = GetObjectLabelFromPointer(length, label);
868 object->setLabel(labelName);
869}
870
871void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
872{
873 LabeledObject *object = getLabeledObjectFromPtr(ptr);
874 ASSERT(object != nullptr);
875
876 std::string labelName = GetObjectLabelFromPointer(length, label);
877 object->setLabel(labelName);
878}
879
880void Context::getObjectLabel(GLenum identifier,
881 GLuint name,
882 GLsizei bufSize,
883 GLsizei *length,
884 GLchar *label) const
885{
886 LabeledObject *object = getLabeledObject(identifier, name);
887 ASSERT(object != nullptr);
888
889 const std::string &objectLabel = object->getLabel();
890 GetObjectLabelBase(objectLabel, bufSize, length, label);
891}
892
893void Context::getObjectPtrLabel(const void *ptr,
894 GLsizei bufSize,
895 GLsizei *length,
896 GLchar *label) const
897{
898 LabeledObject *object = getLabeledObjectFromPtr(ptr);
899 ASSERT(object != nullptr);
900
901 const std::string &objectLabel = object->getLabel();
902 GetObjectLabelBase(objectLabel, bufSize, length, label);
903}
904
Jamie Madilldc356042013-07-19 16:36:57 -0400905bool Context::isSampler(GLuint samplerName) const
906{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500907 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400908}
909
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500910void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000911{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500912 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400913 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000914}
915
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800916void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
917{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500918 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400919 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800920}
921
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500922void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000923{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500924 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400925 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000926}
927
Jamie Madilldedd7b92014-11-05 16:30:36 -0500928void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000929{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500930 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000931
Jamie Madilldedd7b92014-11-05 16:30:36 -0500932 if (handle == 0)
933 {
934 texture = mZeroTextures[target].get();
935 }
936 else
937 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500938 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500939 }
940
941 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400942 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000943}
944
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500945void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000946{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500947 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
948 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700949 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950}
951
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500952void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500954 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
955 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700956 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000957}
958
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500959void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400960{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500961 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700962 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400963}
964
Shao80957d92017-02-20 21:25:59 +0800965void Context::bindVertexBuffer(GLuint bindingIndex,
966 GLuint bufferHandle,
967 GLintptr offset,
968 GLsizei stride)
969{
970 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400971 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +0800972}
973
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500974void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400975{
Geoff Lang76b10c92014-09-05 16:28:14 -0400976 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400977 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500978 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400979 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400980}
981
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800982void Context::bindImageTexture(GLuint unit,
983 GLuint texture,
984 GLint level,
985 GLboolean layered,
986 GLint layer,
987 GLenum access,
988 GLenum format)
989{
990 Texture *tex = mState.mTextures->getTexture(texture);
991 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
992}
993
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500994void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500996 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400997 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000998}
999
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001000void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1001 GLuint index,
1002 GLintptr offset,
1003 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001004{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001005 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001006 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001007}
1008
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001009void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001010{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001011 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001012 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001013}
1014
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001015void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1016 GLuint index,
1017 GLintptr offset,
1018 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001019{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001020 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001021 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001022}
1023
Jiajia Qin6eafb042016-12-27 17:04:07 +08001024void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1025{
1026 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001027 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001028}
1029
1030void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1031 GLuint index,
1032 GLintptr offset,
1033 GLsizeiptr size)
1034{
1035 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001036 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001037}
1038
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001039void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1040{
1041 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001042 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001043}
1044
1045void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1046 GLuint index,
1047 GLintptr offset,
1048 GLsizeiptr size)
1049{
1050 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001051 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001052}
1053
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001054void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001055{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001056 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001057 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001061{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001062 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001063 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001067{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001068 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001069 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001070}
1071
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001072void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001073{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001074 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001075 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001076}
1077
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001078void Context::useProgram(GLuint program)
1079{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001080 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001081}
1082
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001083void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001084{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001085 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001086 TransformFeedback *transformFeedback =
1087 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001088 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001089}
1090
Jamie Madillf0e04492017-08-26 15:28:42 -04001091void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001092{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001093 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001094 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095
Geoff Lang5aad9672014-09-08 11:10:42 -04001096 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001097 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001098
1099 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001100 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001101}
1102
Jamie Madillf0e04492017-08-26 15:28:42 -04001103void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001104{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001105 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001106 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001107
Jamie Madillf0e04492017-08-26 15:28:42 -04001108 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001109
Geoff Lang5aad9672014-09-08 11:10:42 -04001110 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001111 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001112}
1113
Jamie Madillf0e04492017-08-26 15:28:42 -04001114void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001115{
1116 ASSERT(target == GL_TIMESTAMP_EXT);
1117
1118 Query *queryObject = getQuery(id, true, target);
1119 ASSERT(queryObject);
1120
Jamie Madillf0e04492017-08-26 15:28:42 -04001121 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001122}
1123
1124void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1125{
1126 switch (pname)
1127 {
1128 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001129 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001130 break;
1131 case GL_QUERY_COUNTER_BITS_EXT:
1132 switch (target)
1133 {
1134 case GL_TIME_ELAPSED_EXT:
1135 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1136 break;
1137 case GL_TIMESTAMP_EXT:
1138 params[0] = getExtensions().queryCounterBitsTimestamp;
1139 break;
1140 default:
1141 UNREACHABLE();
1142 params[0] = 0;
1143 break;
1144 }
1145 break;
1146 default:
1147 UNREACHABLE();
1148 return;
1149 }
1150}
1151
Geoff Lang2186c382016-10-14 10:54:54 -04001152void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001153{
Geoff Lang2186c382016-10-14 10:54:54 -04001154 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001155}
1156
Geoff Lang2186c382016-10-14 10:54:54 -04001157void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001158{
Geoff Lang2186c382016-10-14 10:54:54 -04001159 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001160}
1161
Geoff Lang2186c382016-10-14 10:54:54 -04001162void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001163{
Geoff Lang2186c382016-10-14 10:54:54 -04001164 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001165}
1166
Geoff Lang2186c382016-10-14 10:54:54 -04001167void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001168{
Geoff Lang2186c382016-10-14 10:54:54 -04001169 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001170}
1171
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001172Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001174 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175}
1176
Jamie Madill2f348d22017-06-05 10:50:59 -04001177FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001178{
Jamie Madill96a483b2017-06-27 16:49:21 -04001179 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180}
1181
Jamie Madill2f348d22017-06-05 10:50:59 -04001182Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001183{
Jamie Madill96a483b2017-06-27 16:49:21 -04001184 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001186 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001188
1189 Query *query = mQueryMap.query(handle);
1190 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001191 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001192 query = new Query(mImplementation->createQuery(type), handle);
1193 query->addRef();
1194 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001195 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001196 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197}
1198
Geoff Lang70d0f492015-12-10 17:45:46 -05001199Query *Context::getQuery(GLuint handle) const
1200{
Jamie Madill96a483b2017-06-27 16:49:21 -04001201 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001202}
1203
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001204Texture *Context::getTargetTexture(GLenum target) const
1205{
Ian Ewellbda75592016-04-18 17:25:54 -04001206 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001207 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001208}
1209
Geoff Lang76b10c92014-09-05 16:28:14 -04001210Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001212 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213}
1214
Geoff Lang492a7e42014-11-05 13:27:06 -05001215Compiler *Context::getCompiler() const
1216{
Jamie Madill2f348d22017-06-05 10:50:59 -04001217 if (mCompiler.get() == nullptr)
1218 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001219 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001220 }
1221 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001222}
1223
Jamie Madillc1d770e2017-04-13 17:31:24 -04001224void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225{
1226 switch (pname)
1227 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001228 case GL_SHADER_COMPILER:
1229 *params = GL_TRUE;
1230 break;
1231 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1232 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1233 break;
1234 default:
1235 mGLState.getBooleanv(pname, params);
1236 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238}
1239
Jamie Madillc1d770e2017-04-13 17:31:24 -04001240void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241{
Shannon Woods53a94a82014-06-24 15:20:36 -04001242 // Queries about context capabilities and maximums are answered by Context.
1243 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244 switch (pname)
1245 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001246 case GL_ALIASED_LINE_WIDTH_RANGE:
1247 params[0] = mCaps.minAliasedLineWidth;
1248 params[1] = mCaps.maxAliasedLineWidth;
1249 break;
1250 case GL_ALIASED_POINT_SIZE_RANGE:
1251 params[0] = mCaps.minAliasedPointSize;
1252 params[1] = mCaps.maxAliasedPointSize;
1253 break;
1254 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1255 ASSERT(mExtensions.textureFilterAnisotropic);
1256 *params = mExtensions.maxTextureAnisotropy;
1257 break;
1258 case GL_MAX_TEXTURE_LOD_BIAS:
1259 *params = mCaps.maxLODBias;
1260 break;
1261
1262 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1263 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1264 {
1265 ASSERT(mExtensions.pathRendering);
1266 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1267 memcpy(params, m, 16 * sizeof(GLfloat));
1268 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001269 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001270
Jamie Madill231c7f52017-04-26 13:45:37 -04001271 default:
1272 mGLState.getFloatv(pname, params);
1273 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275}
1276
Jamie Madillc1d770e2017-04-13 17:31:24 -04001277void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278{
Shannon Woods53a94a82014-06-24 15:20:36 -04001279 // Queries about context capabilities and maximums are answered by Context.
1280 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001281
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001282 switch (pname)
1283 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001284 case GL_MAX_VERTEX_ATTRIBS:
1285 *params = mCaps.maxVertexAttributes;
1286 break;
1287 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1288 *params = mCaps.maxVertexUniformVectors;
1289 break;
1290 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1291 *params = mCaps.maxVertexUniformComponents;
1292 break;
1293 case GL_MAX_VARYING_VECTORS:
1294 *params = mCaps.maxVaryingVectors;
1295 break;
1296 case GL_MAX_VARYING_COMPONENTS:
1297 *params = mCaps.maxVertexOutputComponents;
1298 break;
1299 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1300 *params = mCaps.maxCombinedTextureImageUnits;
1301 break;
1302 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1303 *params = mCaps.maxVertexTextureImageUnits;
1304 break;
1305 case GL_MAX_TEXTURE_IMAGE_UNITS:
1306 *params = mCaps.maxTextureImageUnits;
1307 break;
1308 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1309 *params = mCaps.maxFragmentUniformVectors;
1310 break;
1311 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1312 *params = mCaps.maxFragmentUniformComponents;
1313 break;
1314 case GL_MAX_RENDERBUFFER_SIZE:
1315 *params = mCaps.maxRenderbufferSize;
1316 break;
1317 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1318 *params = mCaps.maxColorAttachments;
1319 break;
1320 case GL_MAX_DRAW_BUFFERS_EXT:
1321 *params = mCaps.maxDrawBuffers;
1322 break;
1323 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1324 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1325 case GL_SUBPIXEL_BITS:
1326 *params = 4;
1327 break;
1328 case GL_MAX_TEXTURE_SIZE:
1329 *params = mCaps.max2DTextureSize;
1330 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001331 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1332 *params = mCaps.maxRectangleTextureSize;
1333 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001334 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1335 *params = mCaps.maxCubeMapTextureSize;
1336 break;
1337 case GL_MAX_3D_TEXTURE_SIZE:
1338 *params = mCaps.max3DTextureSize;
1339 break;
1340 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1341 *params = mCaps.maxArrayTextureLayers;
1342 break;
1343 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1344 *params = mCaps.uniformBufferOffsetAlignment;
1345 break;
1346 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1347 *params = mCaps.maxUniformBufferBindings;
1348 break;
1349 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1350 *params = mCaps.maxVertexUniformBlocks;
1351 break;
1352 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1353 *params = mCaps.maxFragmentUniformBlocks;
1354 break;
1355 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1356 *params = mCaps.maxCombinedTextureImageUnits;
1357 break;
1358 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1359 *params = mCaps.maxVertexOutputComponents;
1360 break;
1361 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1362 *params = mCaps.maxFragmentInputComponents;
1363 break;
1364 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1365 *params = mCaps.minProgramTexelOffset;
1366 break;
1367 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1368 *params = mCaps.maxProgramTexelOffset;
1369 break;
1370 case GL_MAJOR_VERSION:
1371 *params = getClientVersion().major;
1372 break;
1373 case GL_MINOR_VERSION:
1374 *params = getClientVersion().minor;
1375 break;
1376 case GL_MAX_ELEMENTS_INDICES:
1377 *params = mCaps.maxElementsIndices;
1378 break;
1379 case GL_MAX_ELEMENTS_VERTICES:
1380 *params = mCaps.maxElementsVertices;
1381 break;
1382 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1383 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1384 break;
1385 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1386 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1387 break;
1388 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1389 *params = mCaps.maxTransformFeedbackSeparateComponents;
1390 break;
1391 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1392 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1393 break;
1394 case GL_MAX_SAMPLES_ANGLE:
1395 *params = mCaps.maxSamples;
1396 break;
1397 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001398 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001399 params[0] = mCaps.maxViewportWidth;
1400 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001401 }
1402 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001403 case GL_COMPRESSED_TEXTURE_FORMATS:
1404 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1405 params);
1406 break;
1407 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1408 *params = mResetStrategy;
1409 break;
1410 case GL_NUM_SHADER_BINARY_FORMATS:
1411 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1412 break;
1413 case GL_SHADER_BINARY_FORMATS:
1414 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1415 break;
1416 case GL_NUM_PROGRAM_BINARY_FORMATS:
1417 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1418 break;
1419 case GL_PROGRAM_BINARY_FORMATS:
1420 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1421 break;
1422 case GL_NUM_EXTENSIONS:
1423 *params = static_cast<GLint>(mExtensionStrings.size());
1424 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001425
Jamie Madill231c7f52017-04-26 13:45:37 -04001426 // GL_KHR_debug
1427 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1428 *params = mExtensions.maxDebugMessageLength;
1429 break;
1430 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1431 *params = mExtensions.maxDebugLoggedMessages;
1432 break;
1433 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1434 *params = mExtensions.maxDebugGroupStackDepth;
1435 break;
1436 case GL_MAX_LABEL_LENGTH:
1437 *params = mExtensions.maxLabelLength;
1438 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001439
Martin Radeve5285d22017-07-14 16:23:53 +03001440 // GL_ANGLE_multiview
1441 case GL_MAX_VIEWS_ANGLE:
1442 *params = mExtensions.maxViews;
1443 break;
1444
Jamie Madill231c7f52017-04-26 13:45:37 -04001445 // GL_EXT_disjoint_timer_query
1446 case GL_GPU_DISJOINT_EXT:
1447 *params = mImplementation->getGPUDisjoint();
1448 break;
1449 case GL_MAX_FRAMEBUFFER_WIDTH:
1450 *params = mCaps.maxFramebufferWidth;
1451 break;
1452 case GL_MAX_FRAMEBUFFER_HEIGHT:
1453 *params = mCaps.maxFramebufferHeight;
1454 break;
1455 case GL_MAX_FRAMEBUFFER_SAMPLES:
1456 *params = mCaps.maxFramebufferSamples;
1457 break;
1458 case GL_MAX_SAMPLE_MASK_WORDS:
1459 *params = mCaps.maxSampleMaskWords;
1460 break;
1461 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1462 *params = mCaps.maxColorTextureSamples;
1463 break;
1464 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1465 *params = mCaps.maxDepthTextureSamples;
1466 break;
1467 case GL_MAX_INTEGER_SAMPLES:
1468 *params = mCaps.maxIntegerSamples;
1469 break;
1470 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1471 *params = mCaps.maxVertexAttribRelativeOffset;
1472 break;
1473 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1474 *params = mCaps.maxVertexAttribBindings;
1475 break;
1476 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1477 *params = mCaps.maxVertexAttribStride;
1478 break;
1479 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1480 *params = mCaps.maxVertexAtomicCounterBuffers;
1481 break;
1482 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1483 *params = mCaps.maxVertexAtomicCounters;
1484 break;
1485 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1486 *params = mCaps.maxVertexImageUniforms;
1487 break;
1488 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1489 *params = mCaps.maxVertexShaderStorageBlocks;
1490 break;
1491 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1492 *params = mCaps.maxFragmentAtomicCounterBuffers;
1493 break;
1494 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1495 *params = mCaps.maxFragmentAtomicCounters;
1496 break;
1497 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1498 *params = mCaps.maxFragmentImageUniforms;
1499 break;
1500 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1501 *params = mCaps.maxFragmentShaderStorageBlocks;
1502 break;
1503 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1504 *params = mCaps.minProgramTextureGatherOffset;
1505 break;
1506 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1507 *params = mCaps.maxProgramTextureGatherOffset;
1508 break;
1509 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1510 *params = mCaps.maxComputeWorkGroupInvocations;
1511 break;
1512 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1513 *params = mCaps.maxComputeUniformBlocks;
1514 break;
1515 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1516 *params = mCaps.maxComputeTextureImageUnits;
1517 break;
1518 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1519 *params = mCaps.maxComputeSharedMemorySize;
1520 break;
1521 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1522 *params = mCaps.maxComputeUniformComponents;
1523 break;
1524 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1525 *params = mCaps.maxComputeAtomicCounterBuffers;
1526 break;
1527 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1528 *params = mCaps.maxComputeAtomicCounters;
1529 break;
1530 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1531 *params = mCaps.maxComputeImageUniforms;
1532 break;
1533 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1534 *params = mCaps.maxCombinedComputeUniformComponents;
1535 break;
1536 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1537 *params = mCaps.maxComputeShaderStorageBlocks;
1538 break;
1539 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1540 *params = mCaps.maxCombinedShaderOutputResources;
1541 break;
1542 case GL_MAX_UNIFORM_LOCATIONS:
1543 *params = mCaps.maxUniformLocations;
1544 break;
1545 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1546 *params = mCaps.maxAtomicCounterBufferBindings;
1547 break;
1548 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1549 *params = mCaps.maxAtomicCounterBufferSize;
1550 break;
1551 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1552 *params = mCaps.maxCombinedAtomicCounterBuffers;
1553 break;
1554 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1555 *params = mCaps.maxCombinedAtomicCounters;
1556 break;
1557 case GL_MAX_IMAGE_UNITS:
1558 *params = mCaps.maxImageUnits;
1559 break;
1560 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1561 *params = mCaps.maxCombinedImageUniforms;
1562 break;
1563 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1564 *params = mCaps.maxShaderStorageBufferBindings;
1565 break;
1566 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1567 *params = mCaps.maxCombinedShaderStorageBlocks;
1568 break;
1569 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1570 *params = mCaps.shaderStorageBufferOffsetAlignment;
1571 break;
1572 default:
1573 mGLState.getIntegerv(this, pname, params);
1574 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001575 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001576}
1577
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001578void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001579{
Shannon Woods53a94a82014-06-24 15:20:36 -04001580 // Queries about context capabilities and maximums are answered by Context.
1581 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001582 switch (pname)
1583 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001584 case GL_MAX_ELEMENT_INDEX:
1585 *params = mCaps.maxElementIndex;
1586 break;
1587 case GL_MAX_UNIFORM_BLOCK_SIZE:
1588 *params = mCaps.maxUniformBlockSize;
1589 break;
1590 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1591 *params = mCaps.maxCombinedVertexUniformComponents;
1592 break;
1593 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1594 *params = mCaps.maxCombinedFragmentUniformComponents;
1595 break;
1596 case GL_MAX_SERVER_WAIT_TIMEOUT:
1597 *params = mCaps.maxServerWaitTimeout;
1598 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001599
Jamie Madill231c7f52017-04-26 13:45:37 -04001600 // GL_EXT_disjoint_timer_query
1601 case GL_TIMESTAMP_EXT:
1602 *params = mImplementation->getTimestamp();
1603 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001604
Jamie Madill231c7f52017-04-26 13:45:37 -04001605 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1606 *params = mCaps.maxShaderStorageBlockSize;
1607 break;
1608 default:
1609 UNREACHABLE();
1610 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001611 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001612}
1613
Geoff Lang70d0f492015-12-10 17:45:46 -05001614void Context::getPointerv(GLenum pname, void **params) const
1615{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001616 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001617}
1618
Martin Radev66fb8202016-07-28 11:45:20 +03001619void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001620{
Shannon Woods53a94a82014-06-24 15:20:36 -04001621 // Queries about context capabilities and maximums are answered by Context.
1622 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001623
1624 GLenum nativeType;
1625 unsigned int numParams;
1626 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1627 ASSERT(queryStatus);
1628
1629 if (nativeType == GL_INT)
1630 {
1631 switch (target)
1632 {
1633 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1634 ASSERT(index < 3u);
1635 *data = mCaps.maxComputeWorkGroupCount[index];
1636 break;
1637 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1638 ASSERT(index < 3u);
1639 *data = mCaps.maxComputeWorkGroupSize[index];
1640 break;
1641 default:
1642 mGLState.getIntegeri_v(target, index, data);
1643 }
1644 }
1645 else
1646 {
1647 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1648 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001649}
1650
Martin Radev66fb8202016-07-28 11:45:20 +03001651void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001652{
Shannon Woods53a94a82014-06-24 15:20:36 -04001653 // Queries about context capabilities and maximums are answered by Context.
1654 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001655
1656 GLenum nativeType;
1657 unsigned int numParams;
1658 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1659 ASSERT(queryStatus);
1660
1661 if (nativeType == GL_INT_64_ANGLEX)
1662 {
1663 mGLState.getInteger64i_v(target, index, data);
1664 }
1665 else
1666 {
1667 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1668 }
1669}
1670
1671void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1672{
1673 // Queries about context capabilities and maximums are answered by Context.
1674 // Queries about current GL state values are answered by State.
1675
1676 GLenum nativeType;
1677 unsigned int numParams;
1678 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1679 ASSERT(queryStatus);
1680
1681 if (nativeType == GL_BOOL)
1682 {
1683 mGLState.getBooleani_v(target, index, data);
1684 }
1685 else
1686 {
1687 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1688 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001689}
1690
He Yunchao010e4db2017-03-03 14:22:06 +08001691void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1692{
1693 Buffer *buffer = mGLState.getTargetBuffer(target);
1694 QueryBufferParameteriv(buffer, pname, params);
1695}
1696
1697void Context::getFramebufferAttachmentParameteriv(GLenum target,
1698 GLenum attachment,
1699 GLenum pname,
1700 GLint *params)
1701{
1702 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1703 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1704}
1705
1706void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1707{
1708 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1709 QueryRenderbufferiv(this, renderbuffer, pname, params);
1710}
1711
1712void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1713{
1714 Texture *texture = getTargetTexture(target);
1715 QueryTexParameterfv(texture, pname, params);
1716}
1717
1718void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1719{
1720 Texture *texture = getTargetTexture(target);
1721 QueryTexParameteriv(texture, pname, params);
1722}
1723void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1724{
1725 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001726 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001727}
1728
1729void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1730{
1731 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001732 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001733}
1734
1735void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1736{
1737 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001738 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001739}
1740
1741void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1742{
1743 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001744 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001745}
1746
Jamie Madill675fe712016-12-19 13:07:54 -05001747void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001748{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001749 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001750 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1751 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001752}
1753
Jamie Madill675fe712016-12-19 13:07:54 -05001754void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001755{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001756 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001757 ANGLE_CONTEXT_TRY(
1758 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1759 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001760}
1761
Jamie Madill876429b2017-04-20 15:46:24 -04001762void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001763{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001764 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001765 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001766}
1767
Jamie Madill675fe712016-12-19 13:07:54 -05001768void Context::drawElementsInstanced(GLenum mode,
1769 GLsizei count,
1770 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001771 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001772 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001773{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001774 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001775 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001776 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001777}
1778
Jamie Madill675fe712016-12-19 13:07:54 -05001779void Context::drawRangeElements(GLenum mode,
1780 GLuint start,
1781 GLuint end,
1782 GLsizei count,
1783 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001784 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001785{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001786 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001787 ANGLE_CONTEXT_TRY(
1788 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001789}
1790
Jamie Madill876429b2017-04-20 15:46:24 -04001791void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001792{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001793 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001794 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001795}
1796
Jamie Madill876429b2017-04-20 15:46:24 -04001797void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001798{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001799 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001800 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001801}
1802
Jamie Madill675fe712016-12-19 13:07:54 -05001803void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001804{
Jamie Madill675fe712016-12-19 13:07:54 -05001805 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001806}
1807
Jamie Madill675fe712016-12-19 13:07:54 -05001808void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001809{
Jamie Madill675fe712016-12-19 13:07:54 -05001810 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001811}
1812
Austin Kinross6ee1e782015-05-29 17:05:37 -07001813void Context::insertEventMarker(GLsizei length, const char *marker)
1814{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001815 ASSERT(mImplementation);
1816 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001817}
1818
1819void Context::pushGroupMarker(GLsizei length, const char *marker)
1820{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001821 ASSERT(mImplementation);
1822 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001823}
1824
1825void Context::popGroupMarker()
1826{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001827 ASSERT(mImplementation);
1828 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001829}
1830
Geoff Langd8605522016-04-13 10:19:12 -04001831void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1832{
1833 Program *programObject = getProgram(program);
1834 ASSERT(programObject);
1835
1836 programObject->bindUniformLocation(location, name);
1837}
1838
Sami Väisänena797e062016-05-12 15:23:40 +03001839void Context::setCoverageModulation(GLenum components)
1840{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001841 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001842}
1843
Sami Väisänene45e53b2016-05-25 10:36:04 +03001844void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1845{
1846 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1847}
1848
1849void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1850{
1851 GLfloat I[16];
1852 angle::Matrix<GLfloat>::setToIdentity(I);
1853
1854 mGLState.loadPathRenderingMatrix(matrixMode, I);
1855}
1856
1857void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1858{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001859 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001860 if (!pathObj)
1861 return;
1862
1863 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1864 syncRendererState();
1865
1866 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1867}
1868
1869void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1870{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001871 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001872 if (!pathObj)
1873 return;
1874
1875 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1876 syncRendererState();
1877
1878 mImplementation->stencilStrokePath(pathObj, reference, mask);
1879}
1880
1881void Context::coverFillPath(GLuint path, GLenum coverMode)
1882{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001883 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001884 if (!pathObj)
1885 return;
1886
1887 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1888 syncRendererState();
1889
1890 mImplementation->coverFillPath(pathObj, coverMode);
1891}
1892
1893void Context::coverStrokePath(GLuint path, GLenum coverMode)
1894{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001895 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001896 if (!pathObj)
1897 return;
1898
1899 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1900 syncRendererState();
1901
1902 mImplementation->coverStrokePath(pathObj, coverMode);
1903}
1904
1905void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1906{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001907 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001908 if (!pathObj)
1909 return;
1910
1911 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1912 syncRendererState();
1913
1914 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1915}
1916
1917void Context::stencilThenCoverStrokePath(GLuint path,
1918 GLint reference,
1919 GLuint mask,
1920 GLenum coverMode)
1921{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001922 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001923 if (!pathObj)
1924 return;
1925
1926 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1927 syncRendererState();
1928
1929 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1930}
1931
Sami Väisänend59ca052016-06-21 16:10:00 +03001932void Context::coverFillPathInstanced(GLsizei numPaths,
1933 GLenum pathNameType,
1934 const void *paths,
1935 GLuint pathBase,
1936 GLenum coverMode,
1937 GLenum transformType,
1938 const GLfloat *transformValues)
1939{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001940 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001941
1942 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1943 syncRendererState();
1944
1945 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1946}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001947
Sami Väisänend59ca052016-06-21 16:10:00 +03001948void Context::coverStrokePathInstanced(GLsizei numPaths,
1949 GLenum pathNameType,
1950 const void *paths,
1951 GLuint pathBase,
1952 GLenum coverMode,
1953 GLenum transformType,
1954 const GLfloat *transformValues)
1955{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001956 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001957
1958 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1959 syncRendererState();
1960
1961 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1962 transformValues);
1963}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001964
Sami Väisänend59ca052016-06-21 16:10:00 +03001965void Context::stencilFillPathInstanced(GLsizei numPaths,
1966 GLenum pathNameType,
1967 const void *paths,
1968 GLuint pathBase,
1969 GLenum fillMode,
1970 GLuint mask,
1971 GLenum transformType,
1972 const GLfloat *transformValues)
1973{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001974 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001975
1976 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1977 syncRendererState();
1978
1979 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1980 transformValues);
1981}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001982
Sami Väisänend59ca052016-06-21 16:10:00 +03001983void Context::stencilStrokePathInstanced(GLsizei numPaths,
1984 GLenum pathNameType,
1985 const void *paths,
1986 GLuint pathBase,
1987 GLint reference,
1988 GLuint mask,
1989 GLenum transformType,
1990 const GLfloat *transformValues)
1991{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001992 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001993
1994 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1995 syncRendererState();
1996
1997 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1998 transformValues);
1999}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002000
Sami Väisänend59ca052016-06-21 16:10:00 +03002001void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2002 GLenum pathNameType,
2003 const void *paths,
2004 GLuint pathBase,
2005 GLenum fillMode,
2006 GLuint mask,
2007 GLenum coverMode,
2008 GLenum transformType,
2009 const GLfloat *transformValues)
2010{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002011 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002012
2013 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2014 syncRendererState();
2015
2016 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2017 transformType, transformValues);
2018}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002019
Sami Väisänend59ca052016-06-21 16:10:00 +03002020void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2021 GLenum pathNameType,
2022 const void *paths,
2023 GLuint pathBase,
2024 GLint reference,
2025 GLuint mask,
2026 GLenum coverMode,
2027 GLenum transformType,
2028 const GLfloat *transformValues)
2029{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002030 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002031
2032 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2033 syncRendererState();
2034
2035 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2036 transformType, transformValues);
2037}
2038
Sami Väisänen46eaa942016-06-29 10:26:37 +03002039void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2040{
2041 auto *programObject = getProgram(program);
2042
2043 programObject->bindFragmentInputLocation(location, name);
2044}
2045
2046void Context::programPathFragmentInputGen(GLuint program,
2047 GLint location,
2048 GLenum genMode,
2049 GLint components,
2050 const GLfloat *coeffs)
2051{
2052 auto *programObject = getProgram(program);
2053
Jamie Madillbd044ed2017-06-05 12:59:21 -04002054 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002055}
2056
jchen1015015f72017-03-16 13:54:21 +08002057GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2058{
jchen10fd7c3b52017-03-21 15:36:03 +08002059 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002060 return QueryProgramResourceIndex(programObject, programInterface, name);
2061}
2062
jchen10fd7c3b52017-03-21 15:36:03 +08002063void Context::getProgramResourceName(GLuint program,
2064 GLenum programInterface,
2065 GLuint index,
2066 GLsizei bufSize,
2067 GLsizei *length,
2068 GLchar *name)
2069{
2070 const auto *programObject = getProgram(program);
2071 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2072}
2073
jchen10191381f2017-04-11 13:59:04 +08002074GLint Context::getProgramResourceLocation(GLuint program,
2075 GLenum programInterface,
2076 const GLchar *name)
2077{
2078 const auto *programObject = getProgram(program);
2079 return QueryProgramResourceLocation(programObject, programInterface, name);
2080}
2081
jchen10880683b2017-04-12 16:21:55 +08002082void Context::getProgramResourceiv(GLuint program,
2083 GLenum programInterface,
2084 GLuint index,
2085 GLsizei propCount,
2086 const GLenum *props,
2087 GLsizei bufSize,
2088 GLsizei *length,
2089 GLint *params)
2090{
2091 const auto *programObject = getProgram(program);
2092 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2093 length, params);
2094}
2095
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002096Error Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002097{
Geoff Langda5777c2014-07-11 09:52:58 -04002098 if (error.isError())
2099 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002100 GLenum code = error.getCode();
2101 mErrors.insert(code);
2102 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2103 {
2104 markContextLost();
2105 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002106
2107 if (!error.getMessage().empty())
2108 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002109 auto *debug = &mGLState.getDebug();
2110 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2111 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002112 }
Geoff Langda5777c2014-07-11 09:52:58 -04002113 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002114
2115 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002116}
2117
2118// Get one of the recorded errors and clear its flag, if any.
2119// [OpenGL ES 2.0.24] section 2.5 page 13.
2120GLenum Context::getError()
2121{
Geoff Langda5777c2014-07-11 09:52:58 -04002122 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002123 {
Geoff Langda5777c2014-07-11 09:52:58 -04002124 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002125 }
Geoff Langda5777c2014-07-11 09:52:58 -04002126 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002127 {
Geoff Langda5777c2014-07-11 09:52:58 -04002128 GLenum error = *mErrors.begin();
2129 mErrors.erase(mErrors.begin());
2130 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002131 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002132}
2133
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002134// NOTE: this function should not assume that this context is current!
2135void Context::markContextLost()
2136{
2137 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002138 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002139 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002140 mContextLostForced = true;
2141 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002142 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002143}
2144
2145bool Context::isContextLost()
2146{
2147 return mContextLost;
2148}
2149
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002150GLenum Context::getResetStatus()
2151{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002152 // Even if the application doesn't want to know about resets, we want to know
2153 // as it will allow us to skip all the calls.
2154 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002155 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002156 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002157 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002158 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002159 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002160
2161 // EXT_robustness, section 2.6: If the reset notification behavior is
2162 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2163 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2164 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002165 }
2166
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002167 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2168 // status should be returned at least once, and GL_NO_ERROR should be returned
2169 // once the device has finished resetting.
2170 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002171 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002172 ASSERT(mResetStatus == GL_NO_ERROR);
2173 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002174
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002175 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002176 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002177 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002178 }
2179 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002180 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002181 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002182 // If markContextLost was used to mark the context lost then
2183 // assume that is not recoverable, and continue to report the
2184 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002185 mResetStatus = mImplementation->getResetStatus();
2186 }
Jamie Madill893ab082014-05-16 16:56:10 -04002187
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002188 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002189}
2190
2191bool Context::isResetNotificationEnabled()
2192{
2193 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2194}
2195
Corentin Walleze3b10e82015-05-20 11:06:25 -04002196const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002197{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002198 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002199}
2200
2201EGLenum Context::getClientType() const
2202{
2203 return mClientType;
2204}
2205
2206EGLenum Context::getRenderBuffer() const
2207{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002208 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2209 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002210 {
2211 return EGL_NONE;
2212 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002213
2214 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2215 ASSERT(backAttachment != nullptr);
2216 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002217}
2218
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002219VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002220{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002221 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002222 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2223 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002224 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002225 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2226 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002227
Jamie Madill96a483b2017-06-27 16:49:21 -04002228 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002229 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002230
2231 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002232}
2233
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002234TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002235{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002236 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002237 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2238 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002239 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002240 transformFeedback =
2241 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002242 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002243 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002244 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002245
2246 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002247}
2248
2249bool Context::isVertexArrayGenerated(GLuint vertexArray)
2250{
Jamie Madill96a483b2017-06-27 16:49:21 -04002251 ASSERT(mVertexArrayMap.contains(0));
2252 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002253}
2254
2255bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2256{
Jamie Madill96a483b2017-06-27 16:49:21 -04002257 ASSERT(mTransformFeedbackMap.contains(0));
2258 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002259}
2260
Shannon Woods53a94a82014-06-24 15:20:36 -04002261void Context::detachTexture(GLuint texture)
2262{
2263 // Simple pass-through to State's detachTexture method, as textures do not require
2264 // allocation map management either here or in the resource manager at detach time.
2265 // Zero textures are held by the Context, and we don't attempt to request them from
2266 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002267 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002268}
2269
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002270void Context::detachBuffer(GLuint buffer)
2271{
Yuly Novikov5807a532015-12-03 13:01:22 -05002272 // Simple pass-through to State's detachBuffer method, since
2273 // only buffer attachments to container objects that are bound to the current context
2274 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002275
Yuly Novikov5807a532015-12-03 13:01:22 -05002276 // [OpenGL ES 3.2] section 5.1.2 page 45:
2277 // Attachments to unbound container objects, such as
2278 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2279 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002280 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002281}
2282
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002283void Context::detachFramebuffer(GLuint framebuffer)
2284{
Shannon Woods53a94a82014-06-24 15:20:36 -04002285 // Framebuffer detachment is handled by Context, because 0 is a valid
2286 // Framebuffer object, and a pointer to it must be passed from Context
2287 // to State at binding time.
2288
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002289 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002290 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2291 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2292 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002293
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002294 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002295 {
2296 bindReadFramebuffer(0);
2297 }
2298
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002299 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002300 {
2301 bindDrawFramebuffer(0);
2302 }
2303}
2304
2305void Context::detachRenderbuffer(GLuint renderbuffer)
2306{
Jamie Madilla02315b2017-02-23 14:14:47 -05002307 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002308}
2309
Jamie Madill57a89722013-07-02 11:57:03 -04002310void Context::detachVertexArray(GLuint vertexArray)
2311{
Jamie Madill77a72f62015-04-14 11:18:32 -04002312 // Vertex array detachment is handled by Context, because 0 is a valid
2313 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002314 // binding time.
2315
Jamie Madill57a89722013-07-02 11:57:03 -04002316 // [OpenGL ES 3.0.2] section 2.10 page 43:
2317 // If a vertex array object that is currently bound is deleted, the binding
2318 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002319 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002320 {
2321 bindVertexArray(0);
2322 }
2323}
2324
Geoff Langc8058452014-02-03 12:04:11 -05002325void Context::detachTransformFeedback(GLuint transformFeedback)
2326{
Corentin Walleza2257da2016-04-19 16:43:12 -04002327 // Transform feedback detachment is handled by Context, because 0 is a valid
2328 // transform feedback, and a pointer to it must be passed from Context to State at
2329 // binding time.
2330
2331 // The OpenGL specification doesn't mention what should happen when the currently bound
2332 // transform feedback object is deleted. Since it is a container object, we treat it like
2333 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002334 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002335 {
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04002336 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Corentin Walleza2257da2016-04-19 16:43:12 -04002337 }
Geoff Langc8058452014-02-03 12:04:11 -05002338}
2339
Jamie Madilldc356042013-07-19 16:36:57 -04002340void Context::detachSampler(GLuint sampler)
2341{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002342 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002343}
2344
Jamie Madill3ef140a2017-08-26 23:11:21 -04002345void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002346{
Shaodde78e82017-05-22 14:13:27 +08002347 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002348}
2349
Jamie Madille29d1672013-07-19 16:36:57 -04002350void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2351{
Geoff Langc1984ed2016-10-07 12:41:00 -04002352 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002353 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002354 SetSamplerParameteri(samplerObject, pname, param);
2355}
Jamie Madille29d1672013-07-19 16:36:57 -04002356
Geoff Langc1984ed2016-10-07 12:41:00 -04002357void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2358{
2359 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002360 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002361 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002362}
2363
2364void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2365{
Geoff Langc1984ed2016-10-07 12:41:00 -04002366 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002367 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002368 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002369}
2370
Geoff Langc1984ed2016-10-07 12:41:00 -04002371void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002372{
Geoff Langc1984ed2016-10-07 12:41:00 -04002373 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002374 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002375 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002376}
2377
Geoff Langc1984ed2016-10-07 12:41:00 -04002378void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002379{
Geoff Langc1984ed2016-10-07 12:41:00 -04002380 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002381 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002382 QuerySamplerParameteriv(samplerObject, pname, params);
2383}
Jamie Madill9675b802013-07-19 16:36:59 -04002384
Geoff Langc1984ed2016-10-07 12:41:00 -04002385void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2386{
2387 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002388 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002389 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002390}
2391
Olli Etuahof0fee072016-03-30 15:11:58 +03002392void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2393{
2394 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002395 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002396}
2397
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002398void Context::initRendererString()
2399{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002400 std::ostringstream rendererString;
2401 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002402 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002403 rendererString << ")";
2404
Geoff Langcec35902014-04-16 10:52:36 -04002405 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002406}
2407
Geoff Langc339c4e2016-11-29 10:37:36 -05002408void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002409{
Geoff Langc339c4e2016-11-29 10:37:36 -05002410 const Version &clientVersion = getClientVersion();
2411
2412 std::ostringstream versionString;
2413 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2414 << ANGLE_VERSION_STRING << ")";
2415 mVersionString = MakeStaticString(versionString.str());
2416
2417 std::ostringstream shadingLanguageVersionString;
2418 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2419 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2420 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2421 << ")";
2422 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002423}
2424
Geoff Langcec35902014-04-16 10:52:36 -04002425void Context::initExtensionStrings()
2426{
Geoff Langc339c4e2016-11-29 10:37:36 -05002427 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2428 std::ostringstream combinedStringStream;
2429 std::copy(strings.begin(), strings.end(),
2430 std::ostream_iterator<const char *>(combinedStringStream, " "));
2431 return MakeStaticString(combinedStringStream.str());
2432 };
2433
2434 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002435 for (const auto &extensionString : mExtensions.getStrings())
2436 {
2437 mExtensionStrings.push_back(MakeStaticString(extensionString));
2438 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002439 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002440
Bryan Bernhart58806562017-01-05 13:09:31 -08002441 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2442
Geoff Langc339c4e2016-11-29 10:37:36 -05002443 mRequestableExtensionStrings.clear();
2444 for (const auto &extensionInfo : GetExtensionInfoMap())
2445 {
2446 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002447 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2448 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002449 {
2450 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2451 }
2452 }
2453 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002454}
2455
Geoff Langc339c4e2016-11-29 10:37:36 -05002456const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002457{
Geoff Langc339c4e2016-11-29 10:37:36 -05002458 switch (name)
2459 {
2460 case GL_VENDOR:
2461 return reinterpret_cast<const GLubyte *>("Google Inc.");
2462
2463 case GL_RENDERER:
2464 return reinterpret_cast<const GLubyte *>(mRendererString);
2465
2466 case GL_VERSION:
2467 return reinterpret_cast<const GLubyte *>(mVersionString);
2468
2469 case GL_SHADING_LANGUAGE_VERSION:
2470 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2471
2472 case GL_EXTENSIONS:
2473 return reinterpret_cast<const GLubyte *>(mExtensionString);
2474
2475 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2476 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2477
2478 default:
2479 UNREACHABLE();
2480 return nullptr;
2481 }
Geoff Langcec35902014-04-16 10:52:36 -04002482}
2483
Geoff Langc339c4e2016-11-29 10:37:36 -05002484const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002485{
Geoff Langc339c4e2016-11-29 10:37:36 -05002486 switch (name)
2487 {
2488 case GL_EXTENSIONS:
2489 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2490
2491 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2492 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2493
2494 default:
2495 UNREACHABLE();
2496 return nullptr;
2497 }
Geoff Langcec35902014-04-16 10:52:36 -04002498}
2499
2500size_t Context::getExtensionStringCount() const
2501{
2502 return mExtensionStrings.size();
2503}
2504
Geoff Langc339c4e2016-11-29 10:37:36 -05002505void Context::requestExtension(const char *name)
2506{
2507 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2508 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2509 const auto &extension = extensionInfos.at(name);
2510 ASSERT(extension.Requestable);
2511
2512 if (mExtensions.*(extension.ExtensionsMember))
2513 {
2514 // Extension already enabled
2515 return;
2516 }
2517
2518 mExtensions.*(extension.ExtensionsMember) = true;
2519 updateCaps();
2520 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002521
Jamie Madill2f348d22017-06-05 10:50:59 -04002522 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2523 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002524
2525 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2526 // formats renderable or sampleable.
2527 mState.mTextures->invalidateTextureComplenessCache();
2528 for (auto &zeroTexture : mZeroTextures)
2529 {
2530 zeroTexture.second->invalidateCompletenessCache();
2531 }
2532
2533 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002534}
2535
2536size_t Context::getRequestableExtensionStringCount() const
2537{
2538 return mRequestableExtensionStrings.size();
2539}
2540
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002541void Context::beginTransformFeedback(GLenum primitiveMode)
2542{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002543 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002544 ASSERT(transformFeedback != nullptr);
2545 ASSERT(!transformFeedback->isPaused());
2546
Jamie Madill6c1f6712017-02-14 19:08:04 -05002547 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002548}
2549
2550bool Context::hasActiveTransformFeedback(GLuint program) const
2551{
2552 for (auto pair : mTransformFeedbackMap)
2553 {
2554 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2555 {
2556 return true;
2557 }
2558 }
2559 return false;
2560}
2561
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002562void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002563{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002564 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002565
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002566 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002567
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002568 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002569
Geoff Langeb66a6e2016-10-31 13:06:12 -04002570 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002571 {
2572 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002573 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002574 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002575 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002576 mExtensions.multiview = false;
2577 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002578 }
2579
Geoff Langeb66a6e2016-10-31 13:06:12 -04002580 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002581 {
2582 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002583 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002584 }
2585
Jamie Madill00ed7a12016-05-19 13:13:38 -04002586 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002587 mExtensions.bindUniformLocation = true;
2588 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002589 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002590 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002591 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002592
2593 // Enable the no error extension if the context was created with the flag.
2594 mExtensions.noError = mSkipValidation;
2595
Corentin Wallezccab69d2017-01-27 16:57:15 -05002596 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002597 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002598
Geoff Lang70d0f492015-12-10 17:45:46 -05002599 // Explicitly enable GL_KHR_debug
2600 mExtensions.debug = true;
2601 mExtensions.maxDebugMessageLength = 1024;
2602 mExtensions.maxDebugLoggedMessages = 1024;
2603 mExtensions.maxDebugGroupStackDepth = 1024;
2604 mExtensions.maxLabelLength = 1024;
2605
Geoff Langff5b2d52016-09-07 11:32:23 -04002606 // Explicitly enable GL_ANGLE_robust_client_memory
2607 mExtensions.robustClientMemory = true;
2608
Jamie Madille08a1d32017-03-07 17:24:06 -05002609 // Determine robust resource init availability from EGL.
2610 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002611 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002612
Jamie Madillc43be722017-07-13 16:22:14 -04002613 // Enable the cache control query unconditionally.
2614 mExtensions.programCacheControl = true;
2615
Geoff Lang301d1612014-07-09 10:34:37 -04002616 // Apply implementation limits
2617 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002618 mCaps.maxVertexAttribBindings =
2619 getClientVersion() < ES_3_1
2620 ? mCaps.maxVertexAttributes
2621 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2622
Jamie Madill231c7f52017-04-26 13:45:37 -04002623 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2624 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2625 mCaps.maxVertexOutputComponents =
2626 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002627
Jamie Madill231c7f52017-04-26 13:45:37 -04002628 mCaps.maxFragmentInputComponents =
2629 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002630
Geoff Langc287ea62016-09-16 14:46:51 -04002631 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002632 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002633 for (const auto &extensionInfo : GetExtensionInfoMap())
2634 {
2635 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002636 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002637 {
2638 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2639 }
2640 }
2641
2642 // Generate texture caps
2643 updateCaps();
2644}
2645
2646void Context::updateCaps()
2647{
Geoff Lang900013c2014-07-07 11:32:19 -04002648 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002649 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002650
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002651 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002652 {
Geoff Langca271392017-04-05 12:30:00 -04002653 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002654 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002655
Geoff Langca271392017-04-05 12:30:00 -04002656 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002657
Geoff Lang0d8b7242015-09-09 14:56:53 -04002658 // Update the format caps based on the client version and extensions.
2659 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2660 // ES3.
2661 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002662 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002663 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002664 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002665 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002666 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002667
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002668 // OpenGL ES does not support multisampling with non-rendererable formats
2669 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002670 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002671 (getClientVersion() < ES_3_1 &&
2672 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002673 {
Geoff Langd87878e2014-09-19 15:42:59 -04002674 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002675 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002676 else
2677 {
2678 // We may have limited the max samples for some required renderbuffer formats due to
2679 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2680 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2681
2682 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2683 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2684 // exception of signed and unsigned integer formats."
2685 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2686 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2687 {
2688 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2689 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2690 }
2691
2692 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2693 if (getClientVersion() >= ES_3_1)
2694 {
2695 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2696 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2697 // the exception that the signed and unsigned integer formats are required only to
2698 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2699 // multisamples, which must be at least one."
2700 if (formatInfo.componentType == GL_INT ||
2701 formatInfo.componentType == GL_UNSIGNED_INT)
2702 {
2703 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2704 }
2705
2706 // GLES 3.1 section 19.3.1.
2707 if (formatCaps.texturable)
2708 {
2709 if (formatInfo.depthBits > 0)
2710 {
2711 mCaps.maxDepthTextureSamples =
2712 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2713 }
2714 else if (formatInfo.redBits > 0)
2715 {
2716 mCaps.maxColorTextureSamples =
2717 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2718 }
2719 }
2720 }
2721 }
Geoff Langd87878e2014-09-19 15:42:59 -04002722
2723 if (formatCaps.texturable && formatInfo.compressed)
2724 {
Geoff Langca271392017-04-05 12:30:00 -04002725 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002726 }
2727
Geoff Langca271392017-04-05 12:30:00 -04002728 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002729 }
Jamie Madill32447362017-06-28 14:53:52 -04002730
2731 // If program binary is disabled, blank out the memory cache pointer.
2732 if (!mImplementation->getNativeExtensions().getProgramBinary)
2733 {
2734 mMemoryProgramCache = nullptr;
2735 }
Geoff Lang493daf52014-07-03 13:38:44 -04002736}
2737
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002738void Context::initWorkarounds()
2739{
Jamie Madill761b02c2017-06-23 16:27:06 -04002740 // Apply back-end workarounds.
2741 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2742
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002743 // Lose the context upon out of memory error if the application is
2744 // expecting to watch for those events.
2745 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2746}
2747
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002748Error Context::prepareForDraw(GLenum drawMode)
Jamie Madillb6664922017-07-25 12:55:04 -04002749{
2750 syncRendererState();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002751
2752 InfoLog infoLog;
2753 Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
2754 mMemoryProgramCache, drawMode);
Jamie Madilla836b462017-08-16 14:58:35 -04002755 if (err.isError() || infoLog.getLength() > 0)
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002756 {
2757 WARN() << "Dynamic recompilation error log: " << infoLog.str();
2758 }
2759 return err;
Jamie Madillb6664922017-07-25 12:55:04 -04002760}
2761
Jamie Madill1b94d432015-08-07 13:23:23 -04002762void Context::syncRendererState()
2763{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002764 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002765 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002766 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002767 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002768}
2769
Jamie Madillad9f24e2016-02-12 09:27:24 -05002770void Context::syncRendererState(const State::DirtyBits &bitMask,
2771 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002772{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002773 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002774 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002775 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002776 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002777}
Jamie Madillc29968b2016-01-20 11:17:23 -05002778
2779void Context::blitFramebuffer(GLint srcX0,
2780 GLint srcY0,
2781 GLint srcX1,
2782 GLint srcY1,
2783 GLint dstX0,
2784 GLint dstY0,
2785 GLint dstX1,
2786 GLint dstY1,
2787 GLbitfield mask,
2788 GLenum filter)
2789{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002790 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002791 ASSERT(drawFramebuffer);
2792
2793 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2794 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2795
Jamie Madillad9f24e2016-02-12 09:27:24 -05002796 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002797
Jamie Madillc564c072017-06-01 12:45:42 -04002798 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002799}
Jamie Madillc29968b2016-01-20 11:17:23 -05002800
2801void Context::clear(GLbitfield mask)
2802{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002803 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002804 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002805}
2806
2807void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2808{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002809 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002810 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002811}
2812
2813void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2814{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002815 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002816 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002817}
2818
2819void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2820{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002821 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002822 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002823}
2824
2825void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2826{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002827 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002828 ASSERT(framebufferObject);
2829
2830 // If a buffer is not present, the clear has no effect
2831 if (framebufferObject->getDepthbuffer() == nullptr &&
2832 framebufferObject->getStencilbuffer() == nullptr)
2833 {
2834 return;
2835 }
2836
Jamie Madillad9f24e2016-02-12 09:27:24 -05002837 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002838 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002839}
2840
2841void Context::readPixels(GLint x,
2842 GLint y,
2843 GLsizei width,
2844 GLsizei height,
2845 GLenum format,
2846 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002847 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002848{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002849 if (width == 0 || height == 0)
2850 {
2851 return;
2852 }
2853
Jamie Madillad9f24e2016-02-12 09:27:24 -05002854 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002855
Jamie Madillb6664922017-07-25 12:55:04 -04002856 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2857 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002858
2859 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002860 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002861}
2862
2863void Context::copyTexImage2D(GLenum target,
2864 GLint level,
2865 GLenum internalformat,
2866 GLint x,
2867 GLint y,
2868 GLsizei width,
2869 GLsizei height,
2870 GLint border)
2871{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002872 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002873 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002874
Jamie Madillc29968b2016-01-20 11:17:23 -05002875 Rectangle sourceArea(x, y, width, height);
2876
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002877 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002878 Texture *texture =
2879 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002880 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002881}
2882
2883void Context::copyTexSubImage2D(GLenum target,
2884 GLint level,
2885 GLint xoffset,
2886 GLint yoffset,
2887 GLint x,
2888 GLint y,
2889 GLsizei width,
2890 GLsizei height)
2891{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002892 if (width == 0 || height == 0)
2893 {
2894 return;
2895 }
2896
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002897 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002898 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002899
Jamie Madillc29968b2016-01-20 11:17:23 -05002900 Offset destOffset(xoffset, yoffset, 0);
2901 Rectangle sourceArea(x, y, width, height);
2902
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002903 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002904 Texture *texture =
2905 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002906 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002907}
2908
2909void Context::copyTexSubImage3D(GLenum target,
2910 GLint level,
2911 GLint xoffset,
2912 GLint yoffset,
2913 GLint zoffset,
2914 GLint x,
2915 GLint y,
2916 GLsizei width,
2917 GLsizei height)
2918{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002919 if (width == 0 || height == 0)
2920 {
2921 return;
2922 }
2923
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002924 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002925 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002926
Jamie Madillc29968b2016-01-20 11:17:23 -05002927 Offset destOffset(xoffset, yoffset, zoffset);
2928 Rectangle sourceArea(x, y, width, height);
2929
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002930 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002931 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002932 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002933}
2934
2935void Context::framebufferTexture2D(GLenum target,
2936 GLenum attachment,
2937 GLenum textarget,
2938 GLuint texture,
2939 GLint level)
2940{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002941 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002942 ASSERT(framebuffer);
2943
2944 if (texture != 0)
2945 {
2946 Texture *textureObj = getTexture(texture);
2947
2948 ImageIndex index = ImageIndex::MakeInvalid();
2949
2950 if (textarget == GL_TEXTURE_2D)
2951 {
2952 index = ImageIndex::Make2D(level);
2953 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002954 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
2955 {
2956 index = ImageIndex::MakeRectangle(level);
2957 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002958 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2959 {
2960 ASSERT(level == 0);
2961 index = ImageIndex::Make2DMultisample();
2962 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002963 else
2964 {
2965 ASSERT(IsCubeMapTextureTarget(textarget));
2966 index = ImageIndex::MakeCube(textarget, level);
2967 }
2968
Jamie Madilla02315b2017-02-23 14:14:47 -05002969 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002970 }
2971 else
2972 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002973 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002974 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002975
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002976 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002977}
2978
2979void Context::framebufferRenderbuffer(GLenum target,
2980 GLenum attachment,
2981 GLenum renderbuffertarget,
2982 GLuint renderbuffer)
2983{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002984 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002985 ASSERT(framebuffer);
2986
2987 if (renderbuffer != 0)
2988 {
2989 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002990
2991 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002992 renderbufferObject);
2993 }
2994 else
2995 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002996 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002997 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002998
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002999 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003000}
3001
3002void Context::framebufferTextureLayer(GLenum target,
3003 GLenum attachment,
3004 GLuint texture,
3005 GLint level,
3006 GLint layer)
3007{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003008 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003009 ASSERT(framebuffer);
3010
3011 if (texture != 0)
3012 {
3013 Texture *textureObject = getTexture(texture);
3014
3015 ImageIndex index = ImageIndex::MakeInvalid();
3016
3017 if (textureObject->getTarget() == GL_TEXTURE_3D)
3018 {
3019 index = ImageIndex::Make3D(level, layer);
3020 }
3021 else
3022 {
3023 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3024 index = ImageIndex::Make2DArray(level, layer);
3025 }
3026
Jamie Madilla02315b2017-02-23 14:14:47 -05003027 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003028 }
3029 else
3030 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003031 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003032 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003033
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003034 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003035}
3036
Martin Radev137032d2017-07-13 10:11:12 +03003037void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3038 GLenum attachment,
3039 GLuint texture,
3040 GLint level,
3041 GLint baseViewIndex,
3042 GLsizei numViews)
3043{
Martin Radev82ef7742017-08-08 17:44:58 +03003044 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3045 ASSERT(framebuffer);
3046
3047 if (texture != 0)
3048 {
3049 Texture *textureObj = getTexture(texture);
3050
Martin Radev18b75ba2017-08-15 15:50:40 +03003051 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003052 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3053 numViews, baseViewIndex);
3054 }
3055 else
3056 {
3057 framebuffer->resetAttachment(this, attachment);
3058 }
3059
3060 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003061}
3062
3063void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3064 GLenum attachment,
3065 GLuint texture,
3066 GLint level,
3067 GLsizei numViews,
3068 const GLint *viewportOffsets)
3069{
Martin Radev5dae57b2017-07-14 16:15:55 +03003070 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3071 ASSERT(framebuffer);
3072
3073 if (texture != 0)
3074 {
3075 Texture *textureObj = getTexture(texture);
3076
3077 ImageIndex index = ImageIndex::Make2D(level);
3078 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3079 textureObj, numViews, viewportOffsets);
3080 }
3081 else
3082 {
3083 framebuffer->resetAttachment(this, attachment);
3084 }
3085
3086 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003087}
3088
Jamie Madillc29968b2016-01-20 11:17:23 -05003089void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3090{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003091 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003092 ASSERT(framebuffer);
3093 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003094 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003095}
3096
3097void Context::readBuffer(GLenum mode)
3098{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003099 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003100 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003101 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003102}
3103
3104void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3105{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003106 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003107 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003108
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003109 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003110 ASSERT(framebuffer);
3111
3112 // The specification isn't clear what should be done when the framebuffer isn't complete.
3113 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003114 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003115}
3116
3117void Context::invalidateFramebuffer(GLenum target,
3118 GLsizei numAttachments,
3119 const GLenum *attachments)
3120{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003121 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003122 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003123
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003124 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003125 ASSERT(framebuffer);
3126
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003127 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003128 {
Jamie Madill437fa652016-05-03 15:13:24 -04003129 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003130 }
Jamie Madill437fa652016-05-03 15:13:24 -04003131
Jamie Madill4928b7c2017-06-20 12:57:39 -04003132 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003133}
3134
3135void Context::invalidateSubFramebuffer(GLenum target,
3136 GLsizei numAttachments,
3137 const GLenum *attachments,
3138 GLint x,
3139 GLint y,
3140 GLsizei width,
3141 GLsizei height)
3142{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003143 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003144 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003145
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003146 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003147 ASSERT(framebuffer);
3148
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003149 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003150 {
Jamie Madill437fa652016-05-03 15:13:24 -04003151 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003152 }
Jamie Madill437fa652016-05-03 15:13:24 -04003153
3154 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003155 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003156}
3157
Jamie Madill73a84962016-02-12 09:27:23 -05003158void Context::texImage2D(GLenum target,
3159 GLint level,
3160 GLint internalformat,
3161 GLsizei width,
3162 GLsizei height,
3163 GLint border,
3164 GLenum format,
3165 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003166 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003167{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003168 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003169
3170 Extents size(width, height, 1);
3171 Texture *texture =
3172 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003173 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3174 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003175}
3176
3177void Context::texImage3D(GLenum target,
3178 GLint level,
3179 GLint internalformat,
3180 GLsizei width,
3181 GLsizei height,
3182 GLsizei depth,
3183 GLint border,
3184 GLenum format,
3185 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003186 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003187{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003188 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003189
3190 Extents size(width, height, depth);
3191 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003192 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3193 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003194}
3195
3196void Context::texSubImage2D(GLenum target,
3197 GLint level,
3198 GLint xoffset,
3199 GLint yoffset,
3200 GLsizei width,
3201 GLsizei height,
3202 GLenum format,
3203 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003204 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003205{
3206 // Zero sized uploads are valid but no-ops
3207 if (width == 0 || height == 0)
3208 {
3209 return;
3210 }
3211
Jamie Madillad9f24e2016-02-12 09:27:24 -05003212 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003213
3214 Box area(xoffset, yoffset, 0, width, height, 1);
3215 Texture *texture =
3216 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003217 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3218 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003219}
3220
3221void Context::texSubImage3D(GLenum target,
3222 GLint level,
3223 GLint xoffset,
3224 GLint yoffset,
3225 GLint zoffset,
3226 GLsizei width,
3227 GLsizei height,
3228 GLsizei depth,
3229 GLenum format,
3230 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003231 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003232{
3233 // Zero sized uploads are valid but no-ops
3234 if (width == 0 || height == 0 || depth == 0)
3235 {
3236 return;
3237 }
3238
Jamie Madillad9f24e2016-02-12 09:27:24 -05003239 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003240
3241 Box area(xoffset, yoffset, zoffset, width, height, depth);
3242 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003243 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3244 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003245}
3246
3247void Context::compressedTexImage2D(GLenum target,
3248 GLint level,
3249 GLenum internalformat,
3250 GLsizei width,
3251 GLsizei height,
3252 GLint border,
3253 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003254 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003255{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003256 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003257
3258 Extents size(width, height, 1);
3259 Texture *texture =
3260 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003261 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003262 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003263 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003264}
3265
3266void Context::compressedTexImage3D(GLenum target,
3267 GLint level,
3268 GLenum internalformat,
3269 GLsizei width,
3270 GLsizei height,
3271 GLsizei depth,
3272 GLint border,
3273 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003274 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003275{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003276 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003277
3278 Extents size(width, height, depth);
3279 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003280 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003281 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003282 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003283}
3284
3285void Context::compressedTexSubImage2D(GLenum target,
3286 GLint level,
3287 GLint xoffset,
3288 GLint yoffset,
3289 GLsizei width,
3290 GLsizei height,
3291 GLenum format,
3292 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003293 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003294{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003295 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003296
3297 Box area(xoffset, yoffset, 0, width, height, 1);
3298 Texture *texture =
3299 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003300 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003301 format, imageSize,
3302 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003303}
3304
3305void Context::compressedTexSubImage3D(GLenum target,
3306 GLint level,
3307 GLint xoffset,
3308 GLint yoffset,
3309 GLint zoffset,
3310 GLsizei width,
3311 GLsizei height,
3312 GLsizei depth,
3313 GLenum format,
3314 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003315 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003316{
3317 // Zero sized uploads are valid but no-ops
3318 if (width == 0 || height == 0)
3319 {
3320 return;
3321 }
3322
Jamie Madillad9f24e2016-02-12 09:27:24 -05003323 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003324
3325 Box area(xoffset, yoffset, zoffset, width, height, depth);
3326 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003327 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003328 format, imageSize,
3329 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003330}
3331
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003332void Context::generateMipmap(GLenum target)
3333{
3334 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003335 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003336}
3337
Geoff Lang97073d12016-04-20 10:42:34 -07003338void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003339 GLint sourceLevel,
3340 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003341 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003342 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003343 GLint internalFormat,
3344 GLenum destType,
3345 GLboolean unpackFlipY,
3346 GLboolean unpackPremultiplyAlpha,
3347 GLboolean unpackUnmultiplyAlpha)
3348{
3349 syncStateForTexImage();
3350
3351 gl::Texture *sourceTexture = getTexture(sourceId);
3352 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003353 handleError(destTexture->copyTexture(
3354 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3355 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003356}
3357
3358void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003359 GLint sourceLevel,
3360 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003361 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003362 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003363 GLint xoffset,
3364 GLint yoffset,
3365 GLint x,
3366 GLint y,
3367 GLsizei width,
3368 GLsizei height,
3369 GLboolean unpackFlipY,
3370 GLboolean unpackPremultiplyAlpha,
3371 GLboolean unpackUnmultiplyAlpha)
3372{
3373 // Zero sized copies are valid but no-ops
3374 if (width == 0 || height == 0)
3375 {
3376 return;
3377 }
3378
3379 syncStateForTexImage();
3380
3381 gl::Texture *sourceTexture = getTexture(sourceId);
3382 gl::Texture *destTexture = getTexture(destId);
3383 Offset offset(xoffset, yoffset, 0);
3384 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003385 handleError(destTexture->copySubTexture(
3386 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3387 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003388}
3389
Geoff Lang47110bf2016-04-20 11:13:22 -07003390void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3391{
3392 syncStateForTexImage();
3393
3394 gl::Texture *sourceTexture = getTexture(sourceId);
3395 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003396 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003397}
3398
Geoff Lang496c02d2016-10-20 11:38:11 -07003399void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003400{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003401 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003402 ASSERT(buffer);
3403
Geoff Lang496c02d2016-10-20 11:38:11 -07003404 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003405}
3406
Jamie Madill876429b2017-04-20 15:46:24 -04003407void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003408{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003409 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003410 ASSERT(buffer);
3411
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003412 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003413 if (error.isError())
3414 {
Jamie Madill437fa652016-05-03 15:13:24 -04003415 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003416 return nullptr;
3417 }
3418
3419 return buffer->getMapPointer();
3420}
3421
3422GLboolean Context::unmapBuffer(GLenum target)
3423{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003425 ASSERT(buffer);
3426
3427 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003428 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003429 if (error.isError())
3430 {
Jamie Madill437fa652016-05-03 15:13:24 -04003431 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003432 return GL_FALSE;
3433 }
3434
3435 return result;
3436}
3437
Jamie Madill876429b2017-04-20 15:46:24 -04003438void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003439{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003440 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003441 ASSERT(buffer);
3442
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003443 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003444 if (error.isError())
3445 {
Jamie Madill437fa652016-05-03 15:13:24 -04003446 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003447 return nullptr;
3448 }
3449
3450 return buffer->getMapPointer();
3451}
3452
3453void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3454{
3455 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3456}
3457
Jamie Madillad9f24e2016-02-12 09:27:24 -05003458void Context::syncStateForReadPixels()
3459{
3460 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3461}
3462
3463void Context::syncStateForTexImage()
3464{
3465 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3466}
3467
3468void Context::syncStateForClear()
3469{
3470 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3471}
3472
3473void Context::syncStateForBlit()
3474{
3475 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3476}
3477
Jamie Madillc20ab272016-06-09 07:20:46 -07003478void Context::activeTexture(GLenum texture)
3479{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003480 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003481}
3482
Jamie Madill876429b2017-04-20 15:46:24 -04003483void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003484{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003485 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003486}
3487
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003488void Context::blendEquation(GLenum mode)
3489{
3490 mGLState.setBlendEquation(mode, mode);
3491}
3492
Jamie Madillc20ab272016-06-09 07:20:46 -07003493void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3494{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003495 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003496}
3497
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003498void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3499{
3500 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3501}
3502
Jamie Madillc20ab272016-06-09 07:20:46 -07003503void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3504{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003505 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003506}
3507
Jamie Madill876429b2017-04-20 15:46:24 -04003508void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003509{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003511}
3512
Jamie Madill876429b2017-04-20 15:46:24 -04003513void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003514{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003515 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003516}
3517
3518void Context::clearStencil(GLint s)
3519{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
3523void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3524{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
3528void Context::cullFace(GLenum mode)
3529{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003530 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003531}
3532
3533void Context::depthFunc(GLenum func)
3534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003535 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003536}
3537
3538void Context::depthMask(GLboolean flag)
3539{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003540 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003541}
3542
Jamie Madill876429b2017-04-20 15:46:24 -04003543void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003544{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003545 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003546}
3547
3548void Context::disable(GLenum cap)
3549{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003551}
3552
3553void Context::disableVertexAttribArray(GLuint index)
3554{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003555 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003556}
3557
3558void Context::enable(GLenum cap)
3559{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003560 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003561}
3562
3563void Context::enableVertexAttribArray(GLuint index)
3564{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003565 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003566}
3567
3568void Context::frontFace(GLenum mode)
3569{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003570 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003571}
3572
3573void Context::hint(GLenum target, GLenum mode)
3574{
3575 switch (target)
3576 {
3577 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003578 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003579 break;
3580
3581 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003582 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003583 break;
3584
3585 default:
3586 UNREACHABLE();
3587 return;
3588 }
3589}
3590
3591void Context::lineWidth(GLfloat width)
3592{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003593 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003594}
3595
3596void Context::pixelStorei(GLenum pname, GLint param)
3597{
3598 switch (pname)
3599 {
3600 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003601 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003602 break;
3603
3604 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003605 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003606 break;
3607
3608 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003609 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003610 break;
3611
3612 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003613 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003614 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003615 break;
3616
3617 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003618 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003619 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003620 break;
3621
3622 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003623 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003624 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003625 break;
3626
3627 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003628 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003629 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003630 break;
3631
3632 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003633 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003634 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003635 break;
3636
3637 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003638 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003639 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003640 break;
3641
3642 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003643 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003644 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003645 break;
3646
3647 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003648 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003649 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003650 break;
3651
3652 default:
3653 UNREACHABLE();
3654 return;
3655 }
3656}
3657
3658void Context::polygonOffset(GLfloat factor, GLfloat units)
3659{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003660 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003661}
3662
Jamie Madill876429b2017-04-20 15:46:24 -04003663void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003664{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003665 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003666}
3667
3668void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3669{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003670 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003671}
3672
3673void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3674{
3675 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3676 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003677 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003678 }
3679
3680 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3681 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003682 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003683 }
3684}
3685
3686void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3687{
3688 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3689 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003690 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003691 }
3692
3693 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3694 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003695 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003696 }
3697}
3698
3699void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3700{
3701 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3702 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003703 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003704 }
3705
3706 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3707 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003708 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003709 }
3710}
3711
3712void Context::vertexAttrib1f(GLuint index, GLfloat x)
3713{
3714 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003715 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003716}
3717
3718void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3719{
3720 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003721 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003722}
3723
3724void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3725{
3726 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003727 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003728}
3729
3730void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3731{
3732 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003733 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003734}
3735
3736void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3737{
3738 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003739 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003740}
3741
3742void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3743{
3744 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003745 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003746}
3747
3748void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3749{
3750 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003751 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003752}
3753
3754void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3755{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003756 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003757}
3758
3759void Context::vertexAttribPointer(GLuint index,
3760 GLint size,
3761 GLenum type,
3762 GLboolean normalized,
3763 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003764 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003765{
Shaodde78e82017-05-22 14:13:27 +08003766 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3767 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003768}
3769
Shao80957d92017-02-20 21:25:59 +08003770void Context::vertexAttribFormat(GLuint attribIndex,
3771 GLint size,
3772 GLenum type,
3773 GLboolean normalized,
3774 GLuint relativeOffset)
3775{
3776 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3777 relativeOffset);
3778}
3779
3780void Context::vertexAttribIFormat(GLuint attribIndex,
3781 GLint size,
3782 GLenum type,
3783 GLuint relativeOffset)
3784{
3785 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3786}
3787
3788void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3789{
Shaodde78e82017-05-22 14:13:27 +08003790 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003791}
3792
3793void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3794{
3795 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3796}
3797
Jamie Madillc20ab272016-06-09 07:20:46 -07003798void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3799{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003800 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003801}
3802
3803void Context::vertexAttribIPointer(GLuint index,
3804 GLint size,
3805 GLenum type,
3806 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003807 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003808{
Shaodde78e82017-05-22 14:13:27 +08003809 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3810 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003811}
3812
3813void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3814{
3815 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003816 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003817}
3818
3819void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3820{
3821 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003822 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003823}
3824
3825void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3826{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003827 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003828}
3829
3830void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3831{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003832 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003833}
3834
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003835void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3836{
3837 const VertexAttribCurrentValueData &currentValues =
3838 getGLState().getVertexAttribCurrentValue(index);
3839 const VertexArray *vao = getGLState().getVertexArray();
3840 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3841 currentValues, pname, params);
3842}
3843
3844void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3845{
3846 const VertexAttribCurrentValueData &currentValues =
3847 getGLState().getVertexAttribCurrentValue(index);
3848 const VertexArray *vao = getGLState().getVertexArray();
3849 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3850 currentValues, pname, params);
3851}
3852
3853void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3854{
3855 const VertexAttribCurrentValueData &currentValues =
3856 getGLState().getVertexAttribCurrentValue(index);
3857 const VertexArray *vao = getGLState().getVertexArray();
3858 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3859 currentValues, pname, params);
3860}
3861
3862void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3863{
3864 const VertexAttribCurrentValueData &currentValues =
3865 getGLState().getVertexAttribCurrentValue(index);
3866 const VertexArray *vao = getGLState().getVertexArray();
3867 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3868 currentValues, pname, params);
3869}
3870
Jamie Madill876429b2017-04-20 15:46:24 -04003871void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003872{
3873 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3874 QueryVertexAttribPointerv(attrib, pname, pointer);
3875}
3876
Jamie Madillc20ab272016-06-09 07:20:46 -07003877void Context::debugMessageControl(GLenum source,
3878 GLenum type,
3879 GLenum severity,
3880 GLsizei count,
3881 const GLuint *ids,
3882 GLboolean enabled)
3883{
3884 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003885 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3886 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003887}
3888
3889void Context::debugMessageInsert(GLenum source,
3890 GLenum type,
3891 GLuint id,
3892 GLenum severity,
3893 GLsizei length,
3894 const GLchar *buf)
3895{
3896 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003897 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003898}
3899
3900void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3901{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003902 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003903}
3904
3905GLuint Context::getDebugMessageLog(GLuint count,
3906 GLsizei bufSize,
3907 GLenum *sources,
3908 GLenum *types,
3909 GLuint *ids,
3910 GLenum *severities,
3911 GLsizei *lengths,
3912 GLchar *messageLog)
3913{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003914 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3915 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003916}
3917
3918void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3919{
3920 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003921 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003922}
3923
3924void Context::popDebugGroup()
3925{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003926 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003927}
3928
Jamie Madill876429b2017-04-20 15:46:24 -04003929void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003930{
3931 Buffer *buffer = mGLState.getTargetBuffer(target);
3932 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003933 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003934}
3935
Jamie Madill876429b2017-04-20 15:46:24 -04003936void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003937{
3938 if (data == nullptr)
3939 {
3940 return;
3941 }
3942
3943 Buffer *buffer = mGLState.getTargetBuffer(target);
3944 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003945 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003946}
3947
Jamie Madillef300b12016-10-07 15:12:09 -04003948void Context::attachShader(GLuint program, GLuint shader)
3949{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003950 auto programObject = mState.mShaderPrograms->getProgram(program);
3951 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003952 ASSERT(programObject && shaderObject);
3953 programObject->attachShader(shaderObject);
3954}
3955
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003956const Workarounds &Context::getWorkarounds() const
3957{
3958 return mWorkarounds;
3959}
3960
Jamie Madillb0817d12016-11-01 15:48:31 -04003961void Context::copyBufferSubData(GLenum readTarget,
3962 GLenum writeTarget,
3963 GLintptr readOffset,
3964 GLintptr writeOffset,
3965 GLsizeiptr size)
3966{
3967 // if size is zero, the copy is a successful no-op
3968 if (size == 0)
3969 {
3970 return;
3971 }
3972
3973 // TODO(jmadill): cache these.
3974 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3975 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3976
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003977 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003978}
3979
Jamie Madill01a80ee2016-11-07 12:06:18 -05003980void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3981{
3982 Program *programObject = getProgram(program);
3983 // TODO(jmadill): Re-use this from the validation if possible.
3984 ASSERT(programObject);
3985 programObject->bindAttributeLocation(index, name);
3986}
3987
3988void Context::bindBuffer(GLenum target, GLuint buffer)
3989{
3990 switch (target)
3991 {
3992 case GL_ARRAY_BUFFER:
3993 bindArrayBuffer(buffer);
3994 break;
3995 case GL_ELEMENT_ARRAY_BUFFER:
3996 bindElementArrayBuffer(buffer);
3997 break;
3998 case GL_COPY_READ_BUFFER:
3999 bindCopyReadBuffer(buffer);
4000 break;
4001 case GL_COPY_WRITE_BUFFER:
4002 bindCopyWriteBuffer(buffer);
4003 break;
4004 case GL_PIXEL_PACK_BUFFER:
4005 bindPixelPackBuffer(buffer);
4006 break;
4007 case GL_PIXEL_UNPACK_BUFFER:
4008 bindPixelUnpackBuffer(buffer);
4009 break;
4010 case GL_UNIFORM_BUFFER:
4011 bindGenericUniformBuffer(buffer);
4012 break;
4013 case GL_TRANSFORM_FEEDBACK_BUFFER:
4014 bindGenericTransformFeedbackBuffer(buffer);
4015 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004016 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004017 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004018 break;
4019 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004020 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004021 break;
4022 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004023 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004024 break;
4025 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004026 if (buffer != 0)
4027 {
4028 // Binding buffers to this binding point is not implemented yet.
4029 UNIMPLEMENTED();
4030 }
Geoff Lang3b573612016-10-31 14:08:10 -04004031 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004032
4033 default:
4034 UNREACHABLE();
4035 break;
4036 }
4037}
4038
Jiajia Qin6eafb042016-12-27 17:04:07 +08004039void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4040{
4041 bindBufferRange(target, index, buffer, 0, 0);
4042}
4043
4044void Context::bindBufferRange(GLenum target,
4045 GLuint index,
4046 GLuint buffer,
4047 GLintptr offset,
4048 GLsizeiptr size)
4049{
4050 switch (target)
4051 {
4052 case GL_TRANSFORM_FEEDBACK_BUFFER:
4053 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4054 bindGenericTransformFeedbackBuffer(buffer);
4055 break;
4056 case GL_UNIFORM_BUFFER:
4057 bindIndexedUniformBuffer(buffer, index, offset, size);
4058 bindGenericUniformBuffer(buffer);
4059 break;
4060 case GL_ATOMIC_COUNTER_BUFFER:
4061 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4062 bindGenericAtomicCounterBuffer(buffer);
4063 break;
4064 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004065 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4066 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004067 break;
4068 default:
4069 UNREACHABLE();
4070 break;
4071 }
4072}
4073
Jamie Madill01a80ee2016-11-07 12:06:18 -05004074void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4075{
4076 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4077 {
4078 bindReadFramebuffer(framebuffer);
4079 }
4080
4081 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4082 {
4083 bindDrawFramebuffer(framebuffer);
4084 }
4085}
4086
4087void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4088{
4089 ASSERT(target == GL_RENDERBUFFER);
4090 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004091 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004092 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004093}
4094
JiangYizhoubddc46b2016-12-09 09:50:51 +08004095void Context::texStorage2DMultisample(GLenum target,
4096 GLsizei samples,
4097 GLenum internalformat,
4098 GLsizei width,
4099 GLsizei height,
4100 GLboolean fixedsamplelocations)
4101{
4102 Extents size(width, height, 1);
4103 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004104 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004105 fixedsamplelocations));
4106}
4107
4108void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4109{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004110 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004111 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4112
4113 switch (pname)
4114 {
4115 case GL_SAMPLE_POSITION:
4116 handleError(framebuffer->getSamplePosition(index, val));
4117 break;
4118 default:
4119 UNREACHABLE();
4120 }
4121}
4122
Jamie Madille8fb6402017-02-14 17:56:40 -05004123void Context::renderbufferStorage(GLenum target,
4124 GLenum internalformat,
4125 GLsizei width,
4126 GLsizei height)
4127{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004128 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4129 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4130
Jamie Madille8fb6402017-02-14 17:56:40 -05004131 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004132 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004133}
4134
4135void Context::renderbufferStorageMultisample(GLenum target,
4136 GLsizei samples,
4137 GLenum internalformat,
4138 GLsizei width,
4139 GLsizei height)
4140{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004141 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4142 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004143
4144 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004145 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004146 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004147}
4148
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004149void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4150{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004151 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004152 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004153}
4154
JiangYizhoue18e6392017-02-20 10:32:23 +08004155void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4156{
4157 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4158 QueryFramebufferParameteriv(framebuffer, pname, params);
4159}
4160
4161void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4162{
4163 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4164 SetFramebufferParameteri(framebuffer, pname, param);
4165}
4166
Jamie Madillb3f26b92017-07-19 15:07:41 -04004167Error Context::getScratchBuffer(size_t requstedSizeBytes,
4168 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004169{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004170 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4171 {
4172 return OutOfMemory() << "Failed to allocate internal buffer.";
4173 }
4174 return NoError();
4175}
4176
4177Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4178 angle::MemoryBuffer **zeroBufferOut) const
4179{
4180 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004182 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004183 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004184 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004185}
4186
Xinghua Cao2b396592017-03-29 15:36:04 +08004187void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4188{
4189 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4190 {
4191 return;
4192 }
4193
Jamie Madillfe548342017-06-19 11:13:24 -04004194 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004195}
4196
JiangYizhou165361c2017-06-07 14:56:57 +08004197void Context::texStorage2D(GLenum target,
4198 GLsizei levels,
4199 GLenum internalFormat,
4200 GLsizei width,
4201 GLsizei height)
4202{
4203 Extents size(width, height, 1);
4204 Texture *texture = getTargetTexture(target);
4205 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4206}
4207
4208void Context::texStorage3D(GLenum target,
4209 GLsizei levels,
4210 GLenum internalFormat,
4211 GLsizei width,
4212 GLsizei height,
4213 GLsizei depth)
4214{
4215 Extents size(width, height, depth);
4216 Texture *texture = getTargetTexture(target);
4217 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4218}
4219
Jamie Madillc1d770e2017-04-13 17:31:24 -04004220GLenum Context::checkFramebufferStatus(GLenum target)
4221{
4222 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4223 ASSERT(framebuffer);
4224
4225 return framebuffer->checkStatus(this);
4226}
4227
4228void Context::compileShader(GLuint shader)
4229{
4230 Shader *shaderObject = GetValidShader(this, shader);
4231 if (!shaderObject)
4232 {
4233 return;
4234 }
4235 shaderObject->compile(this);
4236}
4237
4238void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4239{
4240 for (int i = 0; i < n; i++)
4241 {
4242 deleteBuffer(buffers[i]);
4243 }
4244}
4245
4246void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4247{
4248 for (int i = 0; i < n; i++)
4249 {
4250 if (framebuffers[i] != 0)
4251 {
4252 deleteFramebuffer(framebuffers[i]);
4253 }
4254 }
4255}
4256
4257void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4258{
4259 for (int i = 0; i < n; i++)
4260 {
4261 deleteRenderbuffer(renderbuffers[i]);
4262 }
4263}
4264
4265void Context::deleteTextures(GLsizei n, const GLuint *textures)
4266{
4267 for (int i = 0; i < n; i++)
4268 {
4269 if (textures[i] != 0)
4270 {
4271 deleteTexture(textures[i]);
4272 }
4273 }
4274}
4275
4276void Context::detachShader(GLuint program, GLuint shader)
4277{
4278 Program *programObject = getProgram(program);
4279 ASSERT(programObject);
4280
4281 Shader *shaderObject = getShader(shader);
4282 ASSERT(shaderObject);
4283
4284 programObject->detachShader(this, shaderObject);
4285}
4286
4287void Context::genBuffers(GLsizei n, GLuint *buffers)
4288{
4289 for (int i = 0; i < n; i++)
4290 {
4291 buffers[i] = createBuffer();
4292 }
4293}
4294
4295void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4296{
4297 for (int i = 0; i < n; i++)
4298 {
4299 framebuffers[i] = createFramebuffer();
4300 }
4301}
4302
4303void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4304{
4305 for (int i = 0; i < n; i++)
4306 {
4307 renderbuffers[i] = createRenderbuffer();
4308 }
4309}
4310
4311void Context::genTextures(GLsizei n, GLuint *textures)
4312{
4313 for (int i = 0; i < n; i++)
4314 {
4315 textures[i] = createTexture();
4316 }
4317}
4318
4319void Context::getActiveAttrib(GLuint program,
4320 GLuint index,
4321 GLsizei bufsize,
4322 GLsizei *length,
4323 GLint *size,
4324 GLenum *type,
4325 GLchar *name)
4326{
4327 Program *programObject = getProgram(program);
4328 ASSERT(programObject);
4329 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4330}
4331
4332void Context::getActiveUniform(GLuint program,
4333 GLuint index,
4334 GLsizei bufsize,
4335 GLsizei *length,
4336 GLint *size,
4337 GLenum *type,
4338 GLchar *name)
4339{
4340 Program *programObject = getProgram(program);
4341 ASSERT(programObject);
4342 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4343}
4344
4345void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4346{
4347 Program *programObject = getProgram(program);
4348 ASSERT(programObject);
4349 programObject->getAttachedShaders(maxcount, count, shaders);
4350}
4351
4352GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4353{
4354 Program *programObject = getProgram(program);
4355 ASSERT(programObject);
4356 return programObject->getAttributeLocation(name);
4357}
4358
4359void Context::getBooleanv(GLenum pname, GLboolean *params)
4360{
4361 GLenum nativeType;
4362 unsigned int numParams = 0;
4363 getQueryParameterInfo(pname, &nativeType, &numParams);
4364
4365 if (nativeType == GL_BOOL)
4366 {
4367 getBooleanvImpl(pname, params);
4368 }
4369 else
4370 {
4371 CastStateValues(this, nativeType, pname, numParams, params);
4372 }
4373}
4374
4375void Context::getFloatv(GLenum pname, GLfloat *params)
4376{
4377 GLenum nativeType;
4378 unsigned int numParams = 0;
4379 getQueryParameterInfo(pname, &nativeType, &numParams);
4380
4381 if (nativeType == GL_FLOAT)
4382 {
4383 getFloatvImpl(pname, params);
4384 }
4385 else
4386 {
4387 CastStateValues(this, nativeType, pname, numParams, params);
4388 }
4389}
4390
4391void Context::getIntegerv(GLenum pname, GLint *params)
4392{
4393 GLenum nativeType;
4394 unsigned int numParams = 0;
4395 getQueryParameterInfo(pname, &nativeType, &numParams);
4396
4397 if (nativeType == GL_INT)
4398 {
4399 getIntegervImpl(pname, params);
4400 }
4401 else
4402 {
4403 CastStateValues(this, nativeType, pname, numParams, params);
4404 }
4405}
4406
4407void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4408{
4409 Program *programObject = getProgram(program);
4410 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004411 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004412}
4413
Jamie Madillbe849e42017-05-02 15:49:00 -04004414void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004415{
4416 Program *programObject = getProgram(program);
4417 ASSERT(programObject);
4418 programObject->getInfoLog(bufsize, length, infolog);
4419}
4420
4421void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4422{
4423 Shader *shaderObject = getShader(shader);
4424 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004425 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004426}
4427
4428void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4429{
4430 Shader *shaderObject = getShader(shader);
4431 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004432 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004433}
4434
4435void Context::getShaderPrecisionFormat(GLenum shadertype,
4436 GLenum precisiontype,
4437 GLint *range,
4438 GLint *precision)
4439{
4440 // TODO(jmadill): Compute shaders.
4441
4442 switch (shadertype)
4443 {
4444 case GL_VERTEX_SHADER:
4445 switch (precisiontype)
4446 {
4447 case GL_LOW_FLOAT:
4448 mCaps.vertexLowpFloat.get(range, precision);
4449 break;
4450 case GL_MEDIUM_FLOAT:
4451 mCaps.vertexMediumpFloat.get(range, precision);
4452 break;
4453 case GL_HIGH_FLOAT:
4454 mCaps.vertexHighpFloat.get(range, precision);
4455 break;
4456
4457 case GL_LOW_INT:
4458 mCaps.vertexLowpInt.get(range, precision);
4459 break;
4460 case GL_MEDIUM_INT:
4461 mCaps.vertexMediumpInt.get(range, precision);
4462 break;
4463 case GL_HIGH_INT:
4464 mCaps.vertexHighpInt.get(range, precision);
4465 break;
4466
4467 default:
4468 UNREACHABLE();
4469 return;
4470 }
4471 break;
4472
4473 case GL_FRAGMENT_SHADER:
4474 switch (precisiontype)
4475 {
4476 case GL_LOW_FLOAT:
4477 mCaps.fragmentLowpFloat.get(range, precision);
4478 break;
4479 case GL_MEDIUM_FLOAT:
4480 mCaps.fragmentMediumpFloat.get(range, precision);
4481 break;
4482 case GL_HIGH_FLOAT:
4483 mCaps.fragmentHighpFloat.get(range, precision);
4484 break;
4485
4486 case GL_LOW_INT:
4487 mCaps.fragmentLowpInt.get(range, precision);
4488 break;
4489 case GL_MEDIUM_INT:
4490 mCaps.fragmentMediumpInt.get(range, precision);
4491 break;
4492 case GL_HIGH_INT:
4493 mCaps.fragmentHighpInt.get(range, precision);
4494 break;
4495
4496 default:
4497 UNREACHABLE();
4498 return;
4499 }
4500 break;
4501
4502 default:
4503 UNREACHABLE();
4504 return;
4505 }
4506}
4507
4508void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4509{
4510 Shader *shaderObject = getShader(shader);
4511 ASSERT(shaderObject);
4512 shaderObject->getSource(bufsize, length, source);
4513}
4514
4515void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4516{
4517 Program *programObject = getProgram(program);
4518 ASSERT(programObject);
4519 programObject->getUniformfv(location, params);
4520}
4521
4522void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4523{
4524 Program *programObject = getProgram(program);
4525 ASSERT(programObject);
4526 programObject->getUniformiv(location, params);
4527}
4528
4529GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4530{
4531 Program *programObject = getProgram(program);
4532 ASSERT(programObject);
4533 return programObject->getUniformLocation(name);
4534}
4535
4536GLboolean Context::isBuffer(GLuint buffer)
4537{
4538 if (buffer == 0)
4539 {
4540 return GL_FALSE;
4541 }
4542
4543 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4544}
4545
4546GLboolean Context::isEnabled(GLenum cap)
4547{
4548 return mGLState.getEnableFeature(cap);
4549}
4550
4551GLboolean Context::isFramebuffer(GLuint framebuffer)
4552{
4553 if (framebuffer == 0)
4554 {
4555 return GL_FALSE;
4556 }
4557
4558 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4559}
4560
4561GLboolean Context::isProgram(GLuint program)
4562{
4563 if (program == 0)
4564 {
4565 return GL_FALSE;
4566 }
4567
4568 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4569}
4570
4571GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4572{
4573 if (renderbuffer == 0)
4574 {
4575 return GL_FALSE;
4576 }
4577
4578 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4579}
4580
4581GLboolean Context::isShader(GLuint shader)
4582{
4583 if (shader == 0)
4584 {
4585 return GL_FALSE;
4586 }
4587
4588 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4589}
4590
4591GLboolean Context::isTexture(GLuint texture)
4592{
4593 if (texture == 0)
4594 {
4595 return GL_FALSE;
4596 }
4597
4598 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4599}
4600
4601void Context::linkProgram(GLuint program)
4602{
4603 Program *programObject = getProgram(program);
4604 ASSERT(programObject);
4605 handleError(programObject->link(this));
4606}
4607
4608void Context::releaseShaderCompiler()
4609{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004610 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004611}
4612
4613void Context::shaderBinary(GLsizei n,
4614 const GLuint *shaders,
4615 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004616 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004617 GLsizei length)
4618{
4619 // No binary shader formats are supported.
4620 UNIMPLEMENTED();
4621}
4622
4623void Context::shaderSource(GLuint shader,
4624 GLsizei count,
4625 const GLchar *const *string,
4626 const GLint *length)
4627{
4628 Shader *shaderObject = getShader(shader);
4629 ASSERT(shaderObject);
4630 shaderObject->setSource(count, string, length);
4631}
4632
4633void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4634{
4635 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4636}
4637
4638void Context::stencilMask(GLuint mask)
4639{
4640 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4641}
4642
4643void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4644{
4645 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4646}
4647
4648void Context::uniform1f(GLint location, GLfloat x)
4649{
4650 Program *program = mGLState.getProgram();
4651 program->setUniform1fv(location, 1, &x);
4652}
4653
4654void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4655{
4656 Program *program = mGLState.getProgram();
4657 program->setUniform1fv(location, count, v);
4658}
4659
4660void Context::uniform1i(GLint location, GLint x)
4661{
4662 Program *program = mGLState.getProgram();
4663 program->setUniform1iv(location, 1, &x);
4664}
4665
4666void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4667{
4668 Program *program = mGLState.getProgram();
4669 program->setUniform1iv(location, count, v);
4670}
4671
4672void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4673{
4674 GLfloat xy[2] = {x, y};
4675 Program *program = mGLState.getProgram();
4676 program->setUniform2fv(location, 1, xy);
4677}
4678
4679void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4680{
4681 Program *program = mGLState.getProgram();
4682 program->setUniform2fv(location, count, v);
4683}
4684
4685void Context::uniform2i(GLint location, GLint x, GLint y)
4686{
4687 GLint xy[2] = {x, y};
4688 Program *program = mGLState.getProgram();
4689 program->setUniform2iv(location, 1, xy);
4690}
4691
4692void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4693{
4694 Program *program = mGLState.getProgram();
4695 program->setUniform2iv(location, count, v);
4696}
4697
4698void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4699{
4700 GLfloat xyz[3] = {x, y, z};
4701 Program *program = mGLState.getProgram();
4702 program->setUniform3fv(location, 1, xyz);
4703}
4704
4705void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4706{
4707 Program *program = mGLState.getProgram();
4708 program->setUniform3fv(location, count, v);
4709}
4710
4711void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4712{
4713 GLint xyz[3] = {x, y, z};
4714 Program *program = mGLState.getProgram();
4715 program->setUniform3iv(location, 1, xyz);
4716}
4717
4718void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4719{
4720 Program *program = mGLState.getProgram();
4721 program->setUniform3iv(location, count, v);
4722}
4723
4724void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4725{
4726 GLfloat xyzw[4] = {x, y, z, w};
4727 Program *program = mGLState.getProgram();
4728 program->setUniform4fv(location, 1, xyzw);
4729}
4730
4731void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4732{
4733 Program *program = mGLState.getProgram();
4734 program->setUniform4fv(location, count, v);
4735}
4736
4737void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4738{
4739 GLint xyzw[4] = {x, y, z, w};
4740 Program *program = mGLState.getProgram();
4741 program->setUniform4iv(location, 1, xyzw);
4742}
4743
4744void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4745{
4746 Program *program = mGLState.getProgram();
4747 program->setUniform4iv(location, count, v);
4748}
4749
4750void Context::uniformMatrix2fv(GLint location,
4751 GLsizei count,
4752 GLboolean transpose,
4753 const GLfloat *value)
4754{
4755 Program *program = mGLState.getProgram();
4756 program->setUniformMatrix2fv(location, count, transpose, value);
4757}
4758
4759void Context::uniformMatrix3fv(GLint location,
4760 GLsizei count,
4761 GLboolean transpose,
4762 const GLfloat *value)
4763{
4764 Program *program = mGLState.getProgram();
4765 program->setUniformMatrix3fv(location, count, transpose, value);
4766}
4767
4768void Context::uniformMatrix4fv(GLint location,
4769 GLsizei count,
4770 GLboolean transpose,
4771 const GLfloat *value)
4772{
4773 Program *program = mGLState.getProgram();
4774 program->setUniformMatrix4fv(location, count, transpose, value);
4775}
4776
4777void Context::validateProgram(GLuint program)
4778{
4779 Program *programObject = getProgram(program);
4780 ASSERT(programObject);
4781 programObject->validate(mCaps);
4782}
4783
Jamie Madilld04908b2017-06-09 14:15:35 -04004784void Context::getProgramBinary(GLuint program,
4785 GLsizei bufSize,
4786 GLsizei *length,
4787 GLenum *binaryFormat,
4788 void *binary)
4789{
4790 Program *programObject = getProgram(program);
4791 ASSERT(programObject != nullptr);
4792
4793 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4794}
4795
4796void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4797{
4798 Program *programObject = getProgram(program);
4799 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004800
Jamie Madilld04908b2017-06-09 14:15:35 -04004801 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4802}
4803
Jamie Madillff325f12017-08-26 15:06:05 -04004804void Context::uniform1ui(GLint location, GLuint v0)
4805{
4806 Program *program = mGLState.getProgram();
4807 program->setUniform1uiv(location, 1, &v0);
4808}
4809
4810void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4811{
4812 Program *program = mGLState.getProgram();
4813 const GLuint xy[] = {v0, v1};
4814 program->setUniform2uiv(location, 1, xy);
4815}
4816
4817void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4818{
4819 Program *program = mGLState.getProgram();
4820 const GLuint xyz[] = {v0, v1, v2};
4821 program->setUniform3uiv(location, 1, xyz);
4822}
4823
4824void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4825{
4826 Program *program = mGLState.getProgram();
4827 const GLuint xyzw[] = {v0, v1, v2, v3};
4828 program->setUniform4uiv(location, 1, xyzw);
4829}
4830
4831void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4832{
4833 Program *program = mGLState.getProgram();
4834 program->setUniform1uiv(location, count, value);
4835}
4836void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4837{
4838 Program *program = mGLState.getProgram();
4839 program->setUniform2uiv(location, count, value);
4840}
4841
4842void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4843{
4844 Program *program = mGLState.getProgram();
4845 program->setUniform3uiv(location, count, value);
4846}
4847
4848void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4849{
4850 Program *program = mGLState.getProgram();
4851 program->setUniform4uiv(location, count, value);
4852}
4853
Jamie Madillf0e04492017-08-26 15:28:42 -04004854void Context::genQueries(GLsizei n, GLuint *ids)
4855{
4856 for (GLsizei i = 0; i < n; i++)
4857 {
4858 GLuint handle = mQueryHandleAllocator.allocate();
4859 mQueryMap.assign(handle, nullptr);
4860 ids[i] = handle;
4861 }
4862}
4863
4864void Context::deleteQueries(GLsizei n, const GLuint *ids)
4865{
4866 for (int i = 0; i < n; i++)
4867 {
4868 GLuint query = ids[i];
4869
4870 Query *queryObject = nullptr;
4871 if (mQueryMap.erase(query, &queryObject))
4872 {
4873 mQueryHandleAllocator.release(query);
4874 if (queryObject)
4875 {
4876 queryObject->release(this);
4877 }
4878 }
4879 }
4880}
4881
4882GLboolean Context::isQuery(GLuint id)
4883{
4884 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4885}
4886
Jamie Madillc8c95812017-08-26 18:40:09 -04004887void Context::uniformMatrix2x3fv(GLint location,
4888 GLsizei count,
4889 GLboolean transpose,
4890 const GLfloat *value)
4891{
4892 Program *program = mGLState.getProgram();
4893 program->setUniformMatrix2x3fv(location, count, transpose, value);
4894}
4895
4896void Context::uniformMatrix3x2fv(GLint location,
4897 GLsizei count,
4898 GLboolean transpose,
4899 const GLfloat *value)
4900{
4901 Program *program = mGLState.getProgram();
4902 program->setUniformMatrix3x2fv(location, count, transpose, value);
4903}
4904
4905void Context::uniformMatrix2x4fv(GLint location,
4906 GLsizei count,
4907 GLboolean transpose,
4908 const GLfloat *value)
4909{
4910 Program *program = mGLState.getProgram();
4911 program->setUniformMatrix2x4fv(location, count, transpose, value);
4912}
4913
4914void Context::uniformMatrix4x2fv(GLint location,
4915 GLsizei count,
4916 GLboolean transpose,
4917 const GLfloat *value)
4918{
4919 Program *program = mGLState.getProgram();
4920 program->setUniformMatrix4x2fv(location, count, transpose, value);
4921}
4922
4923void Context::uniformMatrix3x4fv(GLint location,
4924 GLsizei count,
4925 GLboolean transpose,
4926 const GLfloat *value)
4927{
4928 Program *program = mGLState.getProgram();
4929 program->setUniformMatrix3x4fv(location, count, transpose, value);
4930}
4931
4932void Context::uniformMatrix4x3fv(GLint location,
4933 GLsizei count,
4934 GLboolean transpose,
4935 const GLfloat *value)
4936{
4937 Program *program = mGLState.getProgram();
4938 program->setUniformMatrix4x3fv(location, count, transpose, value);
4939}
4940
Jamie Madilld7576732017-08-26 18:49:50 -04004941void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
4942{
4943 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4944 {
4945 GLuint vertexArray = arrays[arrayIndex];
4946
4947 if (arrays[arrayIndex] != 0)
4948 {
4949 VertexArray *vertexArrayObject = nullptr;
4950 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
4951 {
4952 if (vertexArrayObject != nullptr)
4953 {
4954 detachVertexArray(vertexArray);
4955 vertexArrayObject->onDestroy(this);
4956 }
4957
4958 mVertexArrayHandleAllocator.release(vertexArray);
4959 }
4960 }
4961 }
4962}
4963
4964void Context::genVertexArrays(GLsizei n, GLuint *arrays)
4965{
4966 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4967 {
4968 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
4969 mVertexArrayMap.assign(vertexArray, nullptr);
4970 arrays[arrayIndex] = vertexArray;
4971 }
4972}
4973
4974bool Context::isVertexArray(GLuint array)
4975{
4976 if (array == 0)
4977 {
4978 return GL_FALSE;
4979 }
4980
4981 VertexArray *vao = getVertexArray(array);
4982 return (vao != nullptr ? GL_TRUE : GL_FALSE);
4983}
4984
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04004985void Context::endTransformFeedback()
4986{
4987 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
4988 transformFeedback->end(this);
4989}
4990
4991void Context::transformFeedbackVaryings(GLuint program,
4992 GLsizei count,
4993 const GLchar *const *varyings,
4994 GLenum bufferMode)
4995{
4996 Program *programObject = getProgram(program);
4997 ASSERT(programObject);
4998 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
4999}
5000
5001void Context::getTransformFeedbackVarying(GLuint program,
5002 GLuint index,
5003 GLsizei bufSize,
5004 GLsizei *length,
5005 GLsizei *size,
5006 GLenum *type,
5007 GLchar *name)
5008{
5009 Program *programObject = getProgram(program);
5010 ASSERT(programObject);
5011 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5012}
5013
5014void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5015{
5016 for (int i = 0; i < n; i++)
5017 {
5018 GLuint transformFeedback = ids[i];
5019 if (transformFeedback == 0)
5020 {
5021 continue;
5022 }
5023
5024 TransformFeedback *transformFeedbackObject = nullptr;
5025 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5026 {
5027 if (transformFeedbackObject != nullptr)
5028 {
5029 detachTransformFeedback(transformFeedback);
5030 transformFeedbackObject->release(this);
5031 }
5032
5033 mTransformFeedbackHandleAllocator.release(transformFeedback);
5034 }
5035 }
5036}
5037
5038void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5039{
5040 for (int i = 0; i < n; i++)
5041 {
5042 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5043 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5044 ids[i] = transformFeedback;
5045 }
5046}
5047
5048bool Context::isTransformFeedback(GLuint id)
5049{
5050 if (id == 0)
5051 {
5052 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5053 // returns FALSE
5054 return GL_FALSE;
5055 }
5056
5057 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5058 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5059}
5060
5061void Context::pauseTransformFeedback()
5062{
5063 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5064 transformFeedback->pause();
5065}
5066
5067void Context::resumeTransformFeedback()
5068{
5069 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5070 transformFeedback->resume();
5071}
5072
Jamie Madill12e957f2017-08-26 21:42:26 -04005073void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5074{
5075 const Program *programObject = getProgram(program);
5076 programObject->getUniformuiv(location, params);
5077}
5078
5079GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5080{
5081 const Program *programObject = getProgram(program);
5082 return programObject->getFragDataLocation(name);
5083}
5084
5085void Context::getUniformIndices(GLuint program,
5086 GLsizei uniformCount,
5087 const GLchar *const *uniformNames,
5088 GLuint *uniformIndices)
5089{
5090 const Program *programObject = getProgram(program);
5091 if (!programObject->isLinked())
5092 {
5093 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5094 {
5095 uniformIndices[uniformId] = GL_INVALID_INDEX;
5096 }
5097 }
5098 else
5099 {
5100 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5101 {
5102 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5103 }
5104 }
5105}
5106
5107void Context::getActiveUniformsiv(GLuint program,
5108 GLsizei uniformCount,
5109 const GLuint *uniformIndices,
5110 GLenum pname,
5111 GLint *params)
5112{
5113 const Program *programObject = getProgram(program);
5114 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5115 {
5116 const GLuint index = uniformIndices[uniformId];
5117 params[uniformId] = programObject->getActiveUniformi(index, pname);
5118 }
5119}
5120
5121GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5122{
5123 const Program *programObject = getProgram(program);
5124 return programObject->getUniformBlockIndex(uniformBlockName);
5125}
5126
5127void Context::getActiveUniformBlockiv(GLuint program,
5128 GLuint uniformBlockIndex,
5129 GLenum pname,
5130 GLint *params)
5131{
5132 const Program *programObject = getProgram(program);
5133 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5134}
5135
5136void Context::getActiveUniformBlockName(GLuint program,
5137 GLuint uniformBlockIndex,
5138 GLsizei bufSize,
5139 GLsizei *length,
5140 GLchar *uniformBlockName)
5141{
5142 const Program *programObject = getProgram(program);
5143 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5144}
5145
5146void Context::uniformBlockBinding(GLuint program,
5147 GLuint uniformBlockIndex,
5148 GLuint uniformBlockBinding)
5149{
5150 Program *programObject = getProgram(program);
5151 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5152}
5153
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005154GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5155{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005156 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5157 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005158
Jamie Madill70b5bb02017-08-28 13:32:37 -04005159 Sync *syncObject = getSync(syncHandle);
5160 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005161 if (error.isError())
5162 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005163 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005164 handleError(error);
5165 return nullptr;
5166 }
5167
Jamie Madill70b5bb02017-08-28 13:32:37 -04005168 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005169}
5170
5171GLboolean Context::isSync(GLsync sync)
5172{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005173 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005174}
5175
5176GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5177{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005178 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005179
5180 GLenum result = GL_WAIT_FAILED;
5181 handleError(syncObject->clientWait(flags, timeout, &result));
5182 return result;
5183}
5184
5185void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5186{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005187 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005188 handleError(syncObject->serverWait(flags, timeout));
5189}
5190
5191void Context::getInteger64v(GLenum pname, GLint64 *params)
5192{
5193 GLenum nativeType = GL_NONE;
5194 unsigned int numParams = 0;
5195 getQueryParameterInfo(pname, &nativeType, &numParams);
5196
5197 if (nativeType == GL_INT_64_ANGLEX)
5198 {
5199 getInteger64vImpl(pname, params);
5200 }
5201 else
5202 {
5203 CastStateValues(this, nativeType, pname, numParams, params);
5204 }
5205}
5206
Jamie Madill3ef140a2017-08-26 23:11:21 -04005207void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5208{
5209 Buffer *buffer = mGLState.getTargetBuffer(target);
5210 QueryBufferParameteri64v(buffer, pname, params);
5211}
5212
5213void Context::genSamplers(GLsizei count, GLuint *samplers)
5214{
5215 for (int i = 0; i < count; i++)
5216 {
5217 samplers[i] = mState.mSamplers->createSampler();
5218 }
5219}
5220
5221void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5222{
5223 for (int i = 0; i < count; i++)
5224 {
5225 GLuint sampler = samplers[i];
5226
5227 if (mState.mSamplers->getSampler(sampler))
5228 {
5229 detachSampler(sampler);
5230 }
5231
5232 mState.mSamplers->deleteObject(this, sampler);
5233 }
5234}
5235
5236void Context::getInternalformativ(GLenum target,
5237 GLenum internalformat,
5238 GLenum pname,
5239 GLsizei bufSize,
5240 GLint *params)
5241{
5242 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5243 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5244}
5245
Jamie Madillc29968b2016-01-20 11:17:23 -05005246} // namespace gl