blob: c257e3b6bb66b2b61cdfbfd7e1e2f155bf1e849b [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{
Jamie Madill14bbb3f2017-09-12 15:23:01 -0400283 mImplementation->setMemoryProgramCache(memoryProgramCache);
284
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500285 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700286 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400287
Jamie Madill4928b7c2017-06-20 12:57:39 -0400288 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400289 GetClientArraysEnabled(attribs), robustResourceInit,
290 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100291
Shannon Woods53a94a82014-06-24 15:20:36 -0400292 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400293
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000294 // [OpenGL ES 2.0.24] section 3.7 page 83:
295 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
296 // and cube map texture state vectors respectively associated with them.
297 // In order that access to these initial textures not be lost, they are treated as texture
298 // objects all of whose names are 0.
299
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400300 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400301 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500302
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400304 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400305
Geoff Langeb66a6e2016-10-31 13:06:12 -0400306 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400307 {
308 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400309 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400310 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400311
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400312 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400313 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400314 }
Geoff Lang3b573612016-10-31 14:08:10 -0400315 if (getClientVersion() >= Version(3, 1))
316 {
317 Texture *zeroTexture2DMultisample =
318 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400319 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800320
321 bindGenericAtomicCounterBuffer(0);
322 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
323 {
324 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
325 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800326
327 bindGenericShaderStorageBuffer(0);
328 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
329 {
330 bindIndexedShaderStorageBuffer(0, i, 0, 0);
331 }
Geoff Lang3b573612016-10-31 14:08:10 -0400332 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000333
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400334 if (mExtensions.textureRectangle)
335 {
336 Texture *zeroTextureRectangle =
337 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
338 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
339 }
340
Ian Ewellbda75592016-04-18 17:25:54 -0400341 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
342 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400343 Texture *zeroTextureExternal =
344 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400345 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400346 }
347
Jamie Madill4928b7c2017-06-20 12:57:39 -0400348 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500349
Jamie Madill57a89722013-07-02 11:57:03 -0400350 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000351 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800352 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000353 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400354
Jamie Madill01a80ee2016-11-07 12:06:18 -0500355 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000356
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000357 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500358 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000359 {
360 bindIndexedUniformBuffer(0, i, 0, -1);
361 }
362
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000363 bindCopyReadBuffer(0);
364 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000365 bindPixelPackBuffer(0);
366 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000367
Geoff Langeb66a6e2016-10-31 13:06:12 -0400368 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400369 {
370 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
371 // In the initial state, a default transform feedback object is bound and treated as
372 // a transform feedback object with a name of zero. That object is bound any time
373 // BindTransformFeedback is called with id of zero
Jamie Madillf0dcb8b2017-08-26 19:05:13 -0400374 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Geoff Lang1a683462015-09-29 15:09:59 -0400375 }
Geoff Langc8058452014-02-03 12:04:11 -0500376
Jamie Madillad9f24e2016-02-12 09:27:24 -0500377 // Initialize dirty bit masks
378 // TODO(jmadill): additional ES3 state
379 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
380 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
381 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
382 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
383 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
384 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400385 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500386 // No dirty objects.
387
388 // Readpixels uses the pack state and read FBO
389 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
390 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
391 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
392 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
393 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400394 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500395 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
396
397 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
398 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
399 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
400 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
401 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
402 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
403 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
404 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
405 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
406 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
407 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
408 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
409
410 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
411 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700412 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500413 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
414 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400415
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400416 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000417}
418
Jamie Madill4928b7c2017-06-20 12:57:39 -0400419egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420{
Corentin Wallez80b24112015-08-25 16:41:57 -0400421 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400423 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000424 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400425 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426
Corentin Wallez80b24112015-08-25 16:41:57 -0400427 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000428 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400429 if (query.second != nullptr)
430 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400431 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400432 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000433 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400434 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435
Corentin Wallez80b24112015-08-25 16:41:57 -0400436 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400437 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400438 if (vertexArray.second)
439 {
440 vertexArray.second->onDestroy(this);
441 }
Jamie Madill57a89722013-07-02 11:57:03 -0400442 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400443 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400444
Corentin Wallez80b24112015-08-25 16:41:57 -0400445 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500446 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500447 if (transformFeedback.second != nullptr)
448 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500449 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500450 }
Geoff Langc8058452014-02-03 12:04:11 -0500451 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400452 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500453
Jamie Madilldedd7b92014-11-05 16:30:36 -0500454 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400455 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400456 zeroTexture.second->onDestroy(this);
457 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400458 }
459 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000460
Corentin Wallezccab69d2017-01-27 16:57:15 -0500461 SafeDelete(mSurfacelessFramebuffer);
462
Jamie Madill4928b7c2017-06-20 12:57:39 -0400463 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400464 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500465
Jamie Madill4928b7c2017-06-20 12:57:39 -0400466 mGLState.reset(this);
467
Jamie Madill6c1f6712017-02-14 19:08:04 -0500468 mState.mBuffers->release(this);
469 mState.mShaderPrograms->release(this);
470 mState.mTextures->release(this);
471 mState.mRenderbuffers->release(this);
472 mState.mSamplers->release(this);
Jamie Madill70b5bb02017-08-28 13:32:37 -0400473 mState.mSyncs->release(this);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500474 mState.mPaths->release(this);
475 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400476
477 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000478}
479
Jamie Madill70ee0f62017-02-06 16:04:20 -0500480Context::~Context()
481{
482}
483
Jamie Madill4928b7c2017-06-20 12:57:39 -0400484egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000485{
Jamie Madill61e16b42017-06-19 11:13:23 -0400486 mCurrentDisplay = display;
487
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488 if (!mHasBeenCurrent)
489 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000490 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500491 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400492 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493
Corentin Wallezc295e512017-01-27 17:47:50 -0500494 int width = 0;
495 int height = 0;
496 if (surface != nullptr)
497 {
498 width = surface->getWidth();
499 height = surface->getHeight();
500 }
501
502 mGLState.setViewportParams(0, 0, width, height);
503 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000504
505 mHasBeenCurrent = true;
506 }
507
Jamie Madill1b94d432015-08-07 13:23:23 -0400508 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700509 mGLState.setAllDirtyBits();
Jamie Madill81c2e252017-09-09 23:32:46 -0400510 mGLState.setAllDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -0400511
Jamie Madill4928b7c2017-06-20 12:57:39 -0400512 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500513
514 Framebuffer *newDefault = nullptr;
515 if (surface != nullptr)
516 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400517 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500518 mCurrentSurface = surface;
519 newDefault = surface->getDefaultFramebuffer();
520 }
521 else
522 {
523 if (mSurfacelessFramebuffer == nullptr)
524 {
525 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
526 }
527
528 newDefault = mSurfacelessFramebuffer;
529 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000530
Corentin Wallez37c39792015-08-20 14:19:46 -0400531 // Update default framebuffer, the binding of the previous default
532 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400533 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700534 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400535 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700536 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400537 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700538 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400539 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700540 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400541 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500542 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400543 }
Ian Ewell292f0052016-02-04 10:37:32 -0500544
545 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400546 mImplementation->onMakeCurrent(this);
547 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000548}
549
Jamie Madill4928b7c2017-06-20 12:57:39 -0400550egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400551{
Corentin Wallez37c39792015-08-20 14:19:46 -0400552 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500553 Framebuffer *currentDefault = nullptr;
554 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400555 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500556 currentDefault = mCurrentSurface->getDefaultFramebuffer();
557 }
558 else if (mSurfacelessFramebuffer != nullptr)
559 {
560 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400561 }
562
Corentin Wallezc295e512017-01-27 17:47:50 -0500563 if (mGLState.getReadFramebuffer() == currentDefault)
564 {
565 mGLState.setReadFramebufferBinding(nullptr);
566 }
567 if (mGLState.getDrawFramebuffer() == currentDefault)
568 {
569 mGLState.setDrawFramebufferBinding(nullptr);
570 }
571 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
572
573 if (mCurrentSurface)
574 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400575 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500576 mCurrentSurface = nullptr;
577 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400578
579 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400580}
581
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000582GLuint Context::createBuffer()
583{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500584 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585}
586
587GLuint Context::createProgram()
588{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500589 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000590}
591
592GLuint Context::createShader(GLenum type)
593{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500594 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595}
596
597GLuint Context::createTexture()
598{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500599 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000600}
601
602GLuint Context::createRenderbuffer()
603{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500604 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000605}
606
Sami Väisänene45e53b2016-05-25 10:36:04 +0300607GLuint Context::createPaths(GLsizei range)
608{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500609 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300610 if (resultOrError.isError())
611 {
612 handleError(resultOrError.getError());
613 return 0;
614 }
615 return resultOrError.getResult();
616}
617
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000618// Returns an unused framebuffer name
619GLuint Context::createFramebuffer()
620{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500621 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622}
623
Jamie Madill33dc8432013-07-26 11:55:05 -0400624GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625{
Jamie Madill33dc8432013-07-26 11:55:05 -0400626 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400627 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000628 return handle;
629}
630
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631void Context::deleteBuffer(GLuint buffer)
632{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500633 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000634 {
635 detachBuffer(buffer);
636 }
Jamie Madill893ab082014-05-16 16:56:10 -0400637
Jamie Madill6c1f6712017-02-14 19:08:04 -0500638 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000639}
640
641void Context::deleteShader(GLuint shader)
642{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500643 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000644}
645
646void Context::deleteProgram(GLuint program)
647{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500648 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000649}
650
651void Context::deleteTexture(GLuint texture)
652{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500653 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000654 {
655 detachTexture(texture);
656 }
657
Jamie Madill6c1f6712017-02-14 19:08:04 -0500658 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659}
660
661void Context::deleteRenderbuffer(GLuint renderbuffer)
662{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500663 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000664 {
665 detachRenderbuffer(renderbuffer);
666 }
Jamie Madill893ab082014-05-16 16:56:10 -0400667
Jamie Madill6c1f6712017-02-14 19:08:04 -0500668 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000669}
670
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400671void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400672{
673 // The spec specifies the underlying Fence object is not deleted until all current
674 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
675 // and since our API is currently designed for being called from a single thread, we can delete
676 // the fence immediately.
Jamie Madill70b5bb02017-08-28 13:32:37 -0400677 mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400678}
679
Sami Väisänene45e53b2016-05-25 10:36:04 +0300680void Context::deletePaths(GLuint first, GLsizei range)
681{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500682 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300683}
684
685bool Context::hasPathData(GLuint path) const
686{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500687 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300688 if (pathObj == nullptr)
689 return false;
690
691 return pathObj->hasPathData();
692}
693
694bool Context::hasPath(GLuint path) const
695{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500696 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300697}
698
699void Context::setPathCommands(GLuint path,
700 GLsizei numCommands,
701 const GLubyte *commands,
702 GLsizei numCoords,
703 GLenum coordType,
704 const void *coords)
705{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500706 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300707
708 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
709}
710
711void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
712{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500713 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300714
715 switch (pname)
716 {
717 case GL_PATH_STROKE_WIDTH_CHROMIUM:
718 pathObj->setStrokeWidth(value);
719 break;
720 case GL_PATH_END_CAPS_CHROMIUM:
721 pathObj->setEndCaps(static_cast<GLenum>(value));
722 break;
723 case GL_PATH_JOIN_STYLE_CHROMIUM:
724 pathObj->setJoinStyle(static_cast<GLenum>(value));
725 break;
726 case GL_PATH_MITER_LIMIT_CHROMIUM:
727 pathObj->setMiterLimit(value);
728 break;
729 case GL_PATH_STROKE_BOUND_CHROMIUM:
730 pathObj->setStrokeBound(value);
731 break;
732 default:
733 UNREACHABLE();
734 break;
735 }
736}
737
738void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
739{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500740 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300741
742 switch (pname)
743 {
744 case GL_PATH_STROKE_WIDTH_CHROMIUM:
745 *value = pathObj->getStrokeWidth();
746 break;
747 case GL_PATH_END_CAPS_CHROMIUM:
748 *value = static_cast<GLfloat>(pathObj->getEndCaps());
749 break;
750 case GL_PATH_JOIN_STYLE_CHROMIUM:
751 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
752 break;
753 case GL_PATH_MITER_LIMIT_CHROMIUM:
754 *value = pathObj->getMiterLimit();
755 break;
756 case GL_PATH_STROKE_BOUND_CHROMIUM:
757 *value = pathObj->getStrokeBound();
758 break;
759 default:
760 UNREACHABLE();
761 break;
762 }
763}
764
765void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
766{
767 mGLState.setPathStencilFunc(func, ref, mask);
768}
769
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000770void Context::deleteFramebuffer(GLuint framebuffer)
771{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500772 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000773 {
774 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000775 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500776
Jamie Madill6c1f6712017-02-14 19:08:04 -0500777 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000778}
779
Jamie Madill33dc8432013-07-26 11:55:05 -0400780void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000781{
Jamie Madill96a483b2017-06-27 16:49:21 -0400782 FenceNV *fenceObject = nullptr;
783 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000784 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400785 mFenceNVHandleAllocator.release(fence);
786 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000787 }
788}
789
Geoff Lang70d0f492015-12-10 17:45:46 -0500790Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000791{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500792 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793}
794
Jamie Madill570f7c82014-07-03 10:38:54 -0400795Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500797 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798}
799
Geoff Lang70d0f492015-12-10 17:45:46 -0500800Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500802 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000803}
804
Jamie Madill70b5bb02017-08-28 13:32:37 -0400805Sync *Context::getSync(GLsync handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400806{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400807 return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400808}
809
Jamie Madill57a89722013-07-02 11:57:03 -0400810VertexArray *Context::getVertexArray(GLuint handle) const
811{
Jamie Madill96a483b2017-06-27 16:49:21 -0400812 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400813}
814
Jamie Madilldc356042013-07-19 16:36:57 -0400815Sampler *Context::getSampler(GLuint handle) const
816{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500817 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400818}
819
Geoff Langc8058452014-02-03 12:04:11 -0500820TransformFeedback *Context::getTransformFeedback(GLuint handle) const
821{
Jamie Madill96a483b2017-06-27 16:49:21 -0400822 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500823}
824
Geoff Lang70d0f492015-12-10 17:45:46 -0500825LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
826{
827 switch (identifier)
828 {
829 case GL_BUFFER:
830 return getBuffer(name);
831 case GL_SHADER:
832 return getShader(name);
833 case GL_PROGRAM:
834 return getProgram(name);
835 case GL_VERTEX_ARRAY:
836 return getVertexArray(name);
837 case GL_QUERY:
838 return getQuery(name);
839 case GL_TRANSFORM_FEEDBACK:
840 return getTransformFeedback(name);
841 case GL_SAMPLER:
842 return getSampler(name);
843 case GL_TEXTURE:
844 return getTexture(name);
845 case GL_RENDERBUFFER:
846 return getRenderbuffer(name);
847 case GL_FRAMEBUFFER:
848 return getFramebuffer(name);
849 default:
850 UNREACHABLE();
851 return nullptr;
852 }
853}
854
855LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
856{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400857 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
Geoff Lang70d0f492015-12-10 17:45:46 -0500858}
859
Martin Radev9d901792016-07-15 15:58:58 +0300860void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
861{
862 LabeledObject *object = getLabeledObject(identifier, name);
863 ASSERT(object != nullptr);
864
865 std::string labelName = GetObjectLabelFromPointer(length, label);
866 object->setLabel(labelName);
Jamie Madill8693bdb2017-09-02 15:32:14 -0400867
868 // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
869 // specified object is active until we do this.
870 mGLState.setObjectDirty(identifier);
Martin Radev9d901792016-07-15 15:58:58 +0300871}
872
873void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
874{
875 LabeledObject *object = getLabeledObjectFromPtr(ptr);
876 ASSERT(object != nullptr);
877
878 std::string labelName = GetObjectLabelFromPointer(length, label);
879 object->setLabel(labelName);
880}
881
882void Context::getObjectLabel(GLenum identifier,
883 GLuint name,
884 GLsizei bufSize,
885 GLsizei *length,
886 GLchar *label) const
887{
888 LabeledObject *object = getLabeledObject(identifier, name);
889 ASSERT(object != nullptr);
890
891 const std::string &objectLabel = object->getLabel();
892 GetObjectLabelBase(objectLabel, bufSize, length, label);
893}
894
895void Context::getObjectPtrLabel(const void *ptr,
896 GLsizei bufSize,
897 GLsizei *length,
898 GLchar *label) const
899{
900 LabeledObject *object = getLabeledObjectFromPtr(ptr);
901 ASSERT(object != nullptr);
902
903 const std::string &objectLabel = object->getLabel();
904 GetObjectLabelBase(objectLabel, bufSize, length, label);
905}
906
Jamie Madilldc356042013-07-19 16:36:57 -0400907bool Context::isSampler(GLuint samplerName) const
908{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500909 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400910}
911
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500912void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000913{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500914 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400915 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000916}
917
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800918void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
919{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500920 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400921 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800922}
923
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500924void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000925{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500926 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400927 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000928}
929
Jamie Madilldedd7b92014-11-05 16:30:36 -0500930void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000931{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500932 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000933
Jamie Madilldedd7b92014-11-05 16:30:36 -0500934 if (handle == 0)
935 {
936 texture = mZeroTextures[target].get();
937 }
938 else
939 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500940 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500941 }
942
943 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400944 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000945}
946
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500947void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500949 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
950 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700951 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952}
953
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500954void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500956 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
957 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700958 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000959}
960
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500961void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400962{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500963 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700964 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400965}
966
Shao80957d92017-02-20 21:25:59 +0800967void Context::bindVertexBuffer(GLuint bindingIndex,
968 GLuint bufferHandle,
969 GLintptr offset,
970 GLsizei stride)
971{
972 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400973 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +0800974}
975
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500976void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400977{
Geoff Lang76b10c92014-09-05 16:28:14 -0400978 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400979 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500980 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400981 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400982}
983
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800984void Context::bindImageTexture(GLuint unit,
985 GLuint texture,
986 GLint level,
987 GLboolean layered,
988 GLint layer,
989 GLenum access,
990 GLenum format)
991{
992 Texture *tex = mState.mTextures->getTexture(texture);
993 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
994}
995
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500996void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000997{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500998 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400999 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001000}
1001
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001002void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1003 GLuint index,
1004 GLintptr offset,
1005 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001006{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001007 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001008 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001009}
1010
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001011void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001012{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001013 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001014 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001015}
1016
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001017void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1018 GLuint index,
1019 GLintptr offset,
1020 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001021{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001022 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001023 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001024}
1025
Jiajia Qin6eafb042016-12-27 17:04:07 +08001026void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1027{
1028 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001029 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001030}
1031
1032void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1033 GLuint index,
1034 GLintptr offset,
1035 GLsizeiptr size)
1036{
1037 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001038 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001039}
1040
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001041void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1042{
1043 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001044 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001045}
1046
1047void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1048 GLuint index,
1049 GLintptr offset,
1050 GLsizeiptr size)
1051{
1052 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001053 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001054}
1055
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001056void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001057{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001058 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001059 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001060}
1061
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001062void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001063{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001064 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001065 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001066}
1067
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001068void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001069{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001070 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001071 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001072}
1073
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001074void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001075{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001076 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001077 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001078}
1079
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001080void Context::useProgram(GLuint program)
1081{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001082 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001083}
1084
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001085void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001086{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001087 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001088 TransformFeedback *transformFeedback =
1089 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001090 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001091}
1092
Jamie Madillf0e04492017-08-26 15:28:42 -04001093void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001094{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001096 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001097
Geoff Lang5aad9672014-09-08 11:10:42 -04001098 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001099 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001100
1101 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001102 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001103}
1104
Jamie Madillf0e04492017-08-26 15:28:42 -04001105void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001107 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001108 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001109
Jamie Madillf0e04492017-08-26 15:28:42 -04001110 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001111
Geoff Lang5aad9672014-09-08 11:10:42 -04001112 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001113 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001114}
1115
Jamie Madillf0e04492017-08-26 15:28:42 -04001116void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001117{
1118 ASSERT(target == GL_TIMESTAMP_EXT);
1119
1120 Query *queryObject = getQuery(id, true, target);
1121 ASSERT(queryObject);
1122
Jamie Madillf0e04492017-08-26 15:28:42 -04001123 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001124}
1125
1126void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1127{
1128 switch (pname)
1129 {
1130 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001131 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001132 break;
1133 case GL_QUERY_COUNTER_BITS_EXT:
1134 switch (target)
1135 {
1136 case GL_TIME_ELAPSED_EXT:
1137 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1138 break;
1139 case GL_TIMESTAMP_EXT:
1140 params[0] = getExtensions().queryCounterBitsTimestamp;
1141 break;
1142 default:
1143 UNREACHABLE();
1144 params[0] = 0;
1145 break;
1146 }
1147 break;
1148 default:
1149 UNREACHABLE();
1150 return;
1151 }
1152}
1153
Geoff Lang2186c382016-10-14 10:54:54 -04001154void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001155{
Geoff Lang2186c382016-10-14 10:54:54 -04001156 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001157}
1158
Geoff Lang2186c382016-10-14 10:54:54 -04001159void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001160{
Geoff Lang2186c382016-10-14 10:54:54 -04001161 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001162}
1163
Geoff Lang2186c382016-10-14 10:54:54 -04001164void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001165{
Geoff Lang2186c382016-10-14 10:54:54 -04001166 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001167}
1168
Geoff Lang2186c382016-10-14 10:54:54 -04001169void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001170{
Geoff Lang2186c382016-10-14 10:54:54 -04001171 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001172}
1173
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001174Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001176 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177}
1178
Jamie Madill2f348d22017-06-05 10:50:59 -04001179FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180{
Jamie Madill96a483b2017-06-27 16:49:21 -04001181 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001182}
1183
Jamie Madill2f348d22017-06-05 10:50:59 -04001184Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185{
Jamie Madill96a483b2017-06-27 16:49:21 -04001186 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001188 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001190
1191 Query *query = mQueryMap.query(handle);
1192 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001194 query = new Query(mImplementation->createQuery(type), handle);
1195 query->addRef();
1196 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001198 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001199}
1200
Geoff Lang70d0f492015-12-10 17:45:46 -05001201Query *Context::getQuery(GLuint handle) const
1202{
Jamie Madill96a483b2017-06-27 16:49:21 -04001203 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001204}
1205
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001206Texture *Context::getTargetTexture(GLenum target) const
1207{
Ian Ewellbda75592016-04-18 17:25:54 -04001208 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001209 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001210}
1211
Geoff Lang76b10c92014-09-05 16:28:14 -04001212Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001214 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001215}
1216
Geoff Lang492a7e42014-11-05 13:27:06 -05001217Compiler *Context::getCompiler() const
1218{
Jamie Madill2f348d22017-06-05 10:50:59 -04001219 if (mCompiler.get() == nullptr)
1220 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001221 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001222 }
1223 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001224}
1225
Jamie Madillc1d770e2017-04-13 17:31:24 -04001226void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001227{
1228 switch (pname)
1229 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001230 case GL_SHADER_COMPILER:
1231 *params = GL_TRUE;
1232 break;
1233 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1234 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1235 break;
1236 default:
1237 mGLState.getBooleanv(pname, params);
1238 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001239 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240}
1241
Jamie Madillc1d770e2017-04-13 17:31:24 -04001242void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243{
Shannon Woods53a94a82014-06-24 15:20:36 -04001244 // Queries about context capabilities and maximums are answered by Context.
1245 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246 switch (pname)
1247 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001248 case GL_ALIASED_LINE_WIDTH_RANGE:
1249 params[0] = mCaps.minAliasedLineWidth;
1250 params[1] = mCaps.maxAliasedLineWidth;
1251 break;
1252 case GL_ALIASED_POINT_SIZE_RANGE:
1253 params[0] = mCaps.minAliasedPointSize;
1254 params[1] = mCaps.maxAliasedPointSize;
1255 break;
1256 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1257 ASSERT(mExtensions.textureFilterAnisotropic);
1258 *params = mExtensions.maxTextureAnisotropy;
1259 break;
1260 case GL_MAX_TEXTURE_LOD_BIAS:
1261 *params = mCaps.maxLODBias;
1262 break;
1263
1264 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1265 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1266 {
1267 ASSERT(mExtensions.pathRendering);
1268 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1269 memcpy(params, m, 16 * sizeof(GLfloat));
1270 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001271 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001272
Jamie Madill231c7f52017-04-26 13:45:37 -04001273 default:
1274 mGLState.getFloatv(pname, params);
1275 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277}
1278
Jamie Madillc1d770e2017-04-13 17:31:24 -04001279void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280{
Shannon Woods53a94a82014-06-24 15:20:36 -04001281 // Queries about context capabilities and maximums are answered by Context.
1282 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001283
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284 switch (pname)
1285 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001286 case GL_MAX_VERTEX_ATTRIBS:
1287 *params = mCaps.maxVertexAttributes;
1288 break;
1289 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1290 *params = mCaps.maxVertexUniformVectors;
1291 break;
1292 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1293 *params = mCaps.maxVertexUniformComponents;
1294 break;
1295 case GL_MAX_VARYING_VECTORS:
1296 *params = mCaps.maxVaryingVectors;
1297 break;
1298 case GL_MAX_VARYING_COMPONENTS:
1299 *params = mCaps.maxVertexOutputComponents;
1300 break;
1301 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1302 *params = mCaps.maxCombinedTextureImageUnits;
1303 break;
1304 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1305 *params = mCaps.maxVertexTextureImageUnits;
1306 break;
1307 case GL_MAX_TEXTURE_IMAGE_UNITS:
1308 *params = mCaps.maxTextureImageUnits;
1309 break;
1310 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1311 *params = mCaps.maxFragmentUniformVectors;
1312 break;
1313 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1314 *params = mCaps.maxFragmentUniformComponents;
1315 break;
1316 case GL_MAX_RENDERBUFFER_SIZE:
1317 *params = mCaps.maxRenderbufferSize;
1318 break;
1319 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1320 *params = mCaps.maxColorAttachments;
1321 break;
1322 case GL_MAX_DRAW_BUFFERS_EXT:
1323 *params = mCaps.maxDrawBuffers;
1324 break;
1325 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1326 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1327 case GL_SUBPIXEL_BITS:
1328 *params = 4;
1329 break;
1330 case GL_MAX_TEXTURE_SIZE:
1331 *params = mCaps.max2DTextureSize;
1332 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001333 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1334 *params = mCaps.maxRectangleTextureSize;
1335 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001336 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1337 *params = mCaps.maxCubeMapTextureSize;
1338 break;
1339 case GL_MAX_3D_TEXTURE_SIZE:
1340 *params = mCaps.max3DTextureSize;
1341 break;
1342 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1343 *params = mCaps.maxArrayTextureLayers;
1344 break;
1345 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1346 *params = mCaps.uniformBufferOffsetAlignment;
1347 break;
1348 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1349 *params = mCaps.maxUniformBufferBindings;
1350 break;
1351 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1352 *params = mCaps.maxVertexUniformBlocks;
1353 break;
1354 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1355 *params = mCaps.maxFragmentUniformBlocks;
1356 break;
1357 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1358 *params = mCaps.maxCombinedTextureImageUnits;
1359 break;
1360 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1361 *params = mCaps.maxVertexOutputComponents;
1362 break;
1363 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1364 *params = mCaps.maxFragmentInputComponents;
1365 break;
1366 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1367 *params = mCaps.minProgramTexelOffset;
1368 break;
1369 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1370 *params = mCaps.maxProgramTexelOffset;
1371 break;
1372 case GL_MAJOR_VERSION:
1373 *params = getClientVersion().major;
1374 break;
1375 case GL_MINOR_VERSION:
1376 *params = getClientVersion().minor;
1377 break;
1378 case GL_MAX_ELEMENTS_INDICES:
1379 *params = mCaps.maxElementsIndices;
1380 break;
1381 case GL_MAX_ELEMENTS_VERTICES:
1382 *params = mCaps.maxElementsVertices;
1383 break;
1384 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1385 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1386 break;
1387 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1388 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1389 break;
1390 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1391 *params = mCaps.maxTransformFeedbackSeparateComponents;
1392 break;
1393 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1394 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1395 break;
1396 case GL_MAX_SAMPLES_ANGLE:
1397 *params = mCaps.maxSamples;
1398 break;
1399 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001400 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001401 params[0] = mCaps.maxViewportWidth;
1402 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001403 }
1404 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001405 case GL_COMPRESSED_TEXTURE_FORMATS:
1406 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1407 params);
1408 break;
1409 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1410 *params = mResetStrategy;
1411 break;
1412 case GL_NUM_SHADER_BINARY_FORMATS:
1413 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1414 break;
1415 case GL_SHADER_BINARY_FORMATS:
1416 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1417 break;
1418 case GL_NUM_PROGRAM_BINARY_FORMATS:
1419 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1420 break;
1421 case GL_PROGRAM_BINARY_FORMATS:
1422 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1423 break;
1424 case GL_NUM_EXTENSIONS:
1425 *params = static_cast<GLint>(mExtensionStrings.size());
1426 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001427
Jamie Madill231c7f52017-04-26 13:45:37 -04001428 // GL_KHR_debug
1429 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1430 *params = mExtensions.maxDebugMessageLength;
1431 break;
1432 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1433 *params = mExtensions.maxDebugLoggedMessages;
1434 break;
1435 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1436 *params = mExtensions.maxDebugGroupStackDepth;
1437 break;
1438 case GL_MAX_LABEL_LENGTH:
1439 *params = mExtensions.maxLabelLength;
1440 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001441
Martin Radeve5285d22017-07-14 16:23:53 +03001442 // GL_ANGLE_multiview
1443 case GL_MAX_VIEWS_ANGLE:
1444 *params = mExtensions.maxViews;
1445 break;
1446
Jamie Madill231c7f52017-04-26 13:45:37 -04001447 // GL_EXT_disjoint_timer_query
1448 case GL_GPU_DISJOINT_EXT:
1449 *params = mImplementation->getGPUDisjoint();
1450 break;
1451 case GL_MAX_FRAMEBUFFER_WIDTH:
1452 *params = mCaps.maxFramebufferWidth;
1453 break;
1454 case GL_MAX_FRAMEBUFFER_HEIGHT:
1455 *params = mCaps.maxFramebufferHeight;
1456 break;
1457 case GL_MAX_FRAMEBUFFER_SAMPLES:
1458 *params = mCaps.maxFramebufferSamples;
1459 break;
1460 case GL_MAX_SAMPLE_MASK_WORDS:
1461 *params = mCaps.maxSampleMaskWords;
1462 break;
1463 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1464 *params = mCaps.maxColorTextureSamples;
1465 break;
1466 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1467 *params = mCaps.maxDepthTextureSamples;
1468 break;
1469 case GL_MAX_INTEGER_SAMPLES:
1470 *params = mCaps.maxIntegerSamples;
1471 break;
1472 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1473 *params = mCaps.maxVertexAttribRelativeOffset;
1474 break;
1475 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1476 *params = mCaps.maxVertexAttribBindings;
1477 break;
1478 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1479 *params = mCaps.maxVertexAttribStride;
1480 break;
1481 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1482 *params = mCaps.maxVertexAtomicCounterBuffers;
1483 break;
1484 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1485 *params = mCaps.maxVertexAtomicCounters;
1486 break;
1487 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1488 *params = mCaps.maxVertexImageUniforms;
1489 break;
1490 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1491 *params = mCaps.maxVertexShaderStorageBlocks;
1492 break;
1493 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1494 *params = mCaps.maxFragmentAtomicCounterBuffers;
1495 break;
1496 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1497 *params = mCaps.maxFragmentAtomicCounters;
1498 break;
1499 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1500 *params = mCaps.maxFragmentImageUniforms;
1501 break;
1502 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1503 *params = mCaps.maxFragmentShaderStorageBlocks;
1504 break;
1505 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1506 *params = mCaps.minProgramTextureGatherOffset;
1507 break;
1508 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1509 *params = mCaps.maxProgramTextureGatherOffset;
1510 break;
1511 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1512 *params = mCaps.maxComputeWorkGroupInvocations;
1513 break;
1514 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1515 *params = mCaps.maxComputeUniformBlocks;
1516 break;
1517 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1518 *params = mCaps.maxComputeTextureImageUnits;
1519 break;
1520 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1521 *params = mCaps.maxComputeSharedMemorySize;
1522 break;
1523 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1524 *params = mCaps.maxComputeUniformComponents;
1525 break;
1526 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1527 *params = mCaps.maxComputeAtomicCounterBuffers;
1528 break;
1529 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1530 *params = mCaps.maxComputeAtomicCounters;
1531 break;
1532 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1533 *params = mCaps.maxComputeImageUniforms;
1534 break;
1535 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1536 *params = mCaps.maxCombinedComputeUniformComponents;
1537 break;
1538 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1539 *params = mCaps.maxComputeShaderStorageBlocks;
1540 break;
1541 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1542 *params = mCaps.maxCombinedShaderOutputResources;
1543 break;
1544 case GL_MAX_UNIFORM_LOCATIONS:
1545 *params = mCaps.maxUniformLocations;
1546 break;
1547 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1548 *params = mCaps.maxAtomicCounterBufferBindings;
1549 break;
1550 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1551 *params = mCaps.maxAtomicCounterBufferSize;
1552 break;
1553 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1554 *params = mCaps.maxCombinedAtomicCounterBuffers;
1555 break;
1556 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1557 *params = mCaps.maxCombinedAtomicCounters;
1558 break;
1559 case GL_MAX_IMAGE_UNITS:
1560 *params = mCaps.maxImageUnits;
1561 break;
1562 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1563 *params = mCaps.maxCombinedImageUniforms;
1564 break;
1565 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1566 *params = mCaps.maxShaderStorageBufferBindings;
1567 break;
1568 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1569 *params = mCaps.maxCombinedShaderStorageBlocks;
1570 break;
1571 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1572 *params = mCaps.shaderStorageBufferOffsetAlignment;
1573 break;
1574 default:
1575 mGLState.getIntegerv(this, pname, params);
1576 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001577 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001578}
1579
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001580void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001581{
Shannon Woods53a94a82014-06-24 15:20:36 -04001582 // Queries about context capabilities and maximums are answered by Context.
1583 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001584 switch (pname)
1585 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001586 case GL_MAX_ELEMENT_INDEX:
1587 *params = mCaps.maxElementIndex;
1588 break;
1589 case GL_MAX_UNIFORM_BLOCK_SIZE:
1590 *params = mCaps.maxUniformBlockSize;
1591 break;
1592 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1593 *params = mCaps.maxCombinedVertexUniformComponents;
1594 break;
1595 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1596 *params = mCaps.maxCombinedFragmentUniformComponents;
1597 break;
1598 case GL_MAX_SERVER_WAIT_TIMEOUT:
1599 *params = mCaps.maxServerWaitTimeout;
1600 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001601
Jamie Madill231c7f52017-04-26 13:45:37 -04001602 // GL_EXT_disjoint_timer_query
1603 case GL_TIMESTAMP_EXT:
1604 *params = mImplementation->getTimestamp();
1605 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001606
Jamie Madill231c7f52017-04-26 13:45:37 -04001607 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1608 *params = mCaps.maxShaderStorageBlockSize;
1609 break;
1610 default:
1611 UNREACHABLE();
1612 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001613 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001614}
1615
Geoff Lang70d0f492015-12-10 17:45:46 -05001616void Context::getPointerv(GLenum pname, void **params) const
1617{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001618 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001619}
1620
Martin Radev66fb8202016-07-28 11:45:20 +03001621void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001622{
Shannon Woods53a94a82014-06-24 15:20:36 -04001623 // Queries about context capabilities and maximums are answered by Context.
1624 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001625
1626 GLenum nativeType;
1627 unsigned int numParams;
1628 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1629 ASSERT(queryStatus);
1630
1631 if (nativeType == GL_INT)
1632 {
1633 switch (target)
1634 {
1635 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1636 ASSERT(index < 3u);
1637 *data = mCaps.maxComputeWorkGroupCount[index];
1638 break;
1639 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1640 ASSERT(index < 3u);
1641 *data = mCaps.maxComputeWorkGroupSize[index];
1642 break;
1643 default:
1644 mGLState.getIntegeri_v(target, index, data);
1645 }
1646 }
1647 else
1648 {
1649 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1650 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001651}
1652
Martin Radev66fb8202016-07-28 11:45:20 +03001653void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001654{
Shannon Woods53a94a82014-06-24 15:20:36 -04001655 // Queries about context capabilities and maximums are answered by Context.
1656 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001657
1658 GLenum nativeType;
1659 unsigned int numParams;
1660 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1661 ASSERT(queryStatus);
1662
1663 if (nativeType == GL_INT_64_ANGLEX)
1664 {
1665 mGLState.getInteger64i_v(target, index, data);
1666 }
1667 else
1668 {
1669 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1670 }
1671}
1672
1673void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1674{
1675 // Queries about context capabilities and maximums are answered by Context.
1676 // Queries about current GL state values are answered by State.
1677
1678 GLenum nativeType;
1679 unsigned int numParams;
1680 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1681 ASSERT(queryStatus);
1682
1683 if (nativeType == GL_BOOL)
1684 {
1685 mGLState.getBooleani_v(target, index, data);
1686 }
1687 else
1688 {
1689 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1690 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001691}
1692
He Yunchao010e4db2017-03-03 14:22:06 +08001693void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1694{
1695 Buffer *buffer = mGLState.getTargetBuffer(target);
1696 QueryBufferParameteriv(buffer, pname, params);
1697}
1698
1699void Context::getFramebufferAttachmentParameteriv(GLenum target,
1700 GLenum attachment,
1701 GLenum pname,
1702 GLint *params)
1703{
1704 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1705 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1706}
1707
1708void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1709{
1710 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1711 QueryRenderbufferiv(this, renderbuffer, pname, params);
1712}
1713
1714void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1715{
1716 Texture *texture = getTargetTexture(target);
1717 QueryTexParameterfv(texture, pname, params);
1718}
1719
1720void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1721{
1722 Texture *texture = getTargetTexture(target);
1723 QueryTexParameteriv(texture, pname, params);
1724}
1725void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1726{
1727 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001728 SetTexParameterf(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001729 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001730}
1731
1732void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1733{
1734 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001735 SetTexParameterfv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001736 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001737}
1738
1739void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1740{
1741 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001742 SetTexParameteri(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001743 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001744}
1745
1746void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1747{
1748 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001749 SetTexParameteriv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001750 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001751}
1752
Jamie Madill675fe712016-12-19 13:07:54 -05001753void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001754{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001755 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001756 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1757 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001758}
1759
Jamie Madill675fe712016-12-19 13:07:54 -05001760void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001761{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001762 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001763 ANGLE_CONTEXT_TRY(
1764 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1765 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001766}
1767
Jamie Madill876429b2017-04-20 15:46:24 -04001768void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001769{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001770 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001771 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001772}
1773
Jamie Madill675fe712016-12-19 13:07:54 -05001774void Context::drawElementsInstanced(GLenum mode,
1775 GLsizei count,
1776 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001777 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001778 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001779{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001780 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001781 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001782 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001783}
1784
Jamie Madill675fe712016-12-19 13:07:54 -05001785void Context::drawRangeElements(GLenum mode,
1786 GLuint start,
1787 GLuint end,
1788 GLsizei count,
1789 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001790 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001791{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001792 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001793 ANGLE_CONTEXT_TRY(
1794 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001795}
1796
Jamie Madill876429b2017-04-20 15:46:24 -04001797void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001798{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001799 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001800 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001801}
1802
Jamie Madill876429b2017-04-20 15:46:24 -04001803void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001804{
Jamie Madill14bbb3f2017-09-12 15:23:01 -04001805 syncRendererState();
Jamie Madillb6664922017-07-25 12:55:04 -04001806 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001807}
1808
Jamie Madill675fe712016-12-19 13:07:54 -05001809void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001810{
Jamie Madill675fe712016-12-19 13:07:54 -05001811 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001812}
1813
Jamie Madill675fe712016-12-19 13:07:54 -05001814void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001815{
Jamie Madill675fe712016-12-19 13:07:54 -05001816 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001817}
1818
Austin Kinross6ee1e782015-05-29 17:05:37 -07001819void Context::insertEventMarker(GLsizei length, const char *marker)
1820{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001821 ASSERT(mImplementation);
1822 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001823}
1824
1825void Context::pushGroupMarker(GLsizei length, const char *marker)
1826{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001827 ASSERT(mImplementation);
1828 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001829}
1830
1831void Context::popGroupMarker()
1832{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001833 ASSERT(mImplementation);
1834 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001835}
1836
Geoff Langd8605522016-04-13 10:19:12 -04001837void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1838{
1839 Program *programObject = getProgram(program);
1840 ASSERT(programObject);
1841
1842 programObject->bindUniformLocation(location, name);
1843}
1844
Sami Väisänena797e062016-05-12 15:23:40 +03001845void Context::setCoverageModulation(GLenum components)
1846{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001847 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001848}
1849
Sami Väisänene45e53b2016-05-25 10:36:04 +03001850void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1851{
1852 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1853}
1854
1855void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1856{
1857 GLfloat I[16];
1858 angle::Matrix<GLfloat>::setToIdentity(I);
1859
1860 mGLState.loadPathRenderingMatrix(matrixMode, I);
1861}
1862
1863void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1864{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001865 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001866 if (!pathObj)
1867 return;
1868
1869 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1870 syncRendererState();
1871
1872 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1873}
1874
1875void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1876{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001877 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001878 if (!pathObj)
1879 return;
1880
1881 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1882 syncRendererState();
1883
1884 mImplementation->stencilStrokePath(pathObj, reference, mask);
1885}
1886
1887void Context::coverFillPath(GLuint path, GLenum coverMode)
1888{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001889 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001890 if (!pathObj)
1891 return;
1892
1893 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1894 syncRendererState();
1895
1896 mImplementation->coverFillPath(pathObj, coverMode);
1897}
1898
1899void Context::coverStrokePath(GLuint path, GLenum coverMode)
1900{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001901 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001902 if (!pathObj)
1903 return;
1904
1905 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1906 syncRendererState();
1907
1908 mImplementation->coverStrokePath(pathObj, coverMode);
1909}
1910
1911void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1912{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001913 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001914 if (!pathObj)
1915 return;
1916
1917 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1918 syncRendererState();
1919
1920 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1921}
1922
1923void Context::stencilThenCoverStrokePath(GLuint path,
1924 GLint reference,
1925 GLuint mask,
1926 GLenum coverMode)
1927{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001928 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001929 if (!pathObj)
1930 return;
1931
1932 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1933 syncRendererState();
1934
1935 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1936}
1937
Sami Väisänend59ca052016-06-21 16:10:00 +03001938void Context::coverFillPathInstanced(GLsizei numPaths,
1939 GLenum pathNameType,
1940 const void *paths,
1941 GLuint pathBase,
1942 GLenum coverMode,
1943 GLenum transformType,
1944 const GLfloat *transformValues)
1945{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001946 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001947
1948 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1949 syncRendererState();
1950
1951 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1952}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001953
Sami Väisänend59ca052016-06-21 16:10:00 +03001954void Context::coverStrokePathInstanced(GLsizei numPaths,
1955 GLenum pathNameType,
1956 const void *paths,
1957 GLuint pathBase,
1958 GLenum coverMode,
1959 GLenum transformType,
1960 const GLfloat *transformValues)
1961{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001962 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001963
1964 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1965 syncRendererState();
1966
1967 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1968 transformValues);
1969}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001970
Sami Väisänend59ca052016-06-21 16:10:00 +03001971void Context::stencilFillPathInstanced(GLsizei numPaths,
1972 GLenum pathNameType,
1973 const void *paths,
1974 GLuint pathBase,
1975 GLenum fillMode,
1976 GLuint mask,
1977 GLenum transformType,
1978 const GLfloat *transformValues)
1979{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001980 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001981
1982 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1983 syncRendererState();
1984
1985 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1986 transformValues);
1987}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001988
Sami Väisänend59ca052016-06-21 16:10:00 +03001989void Context::stencilStrokePathInstanced(GLsizei numPaths,
1990 GLenum pathNameType,
1991 const void *paths,
1992 GLuint pathBase,
1993 GLint reference,
1994 GLuint mask,
1995 GLenum transformType,
1996 const GLfloat *transformValues)
1997{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001998 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001999
2000 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2001 syncRendererState();
2002
2003 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2004 transformValues);
2005}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002006
Sami Väisänend59ca052016-06-21 16:10:00 +03002007void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2008 GLenum pathNameType,
2009 const void *paths,
2010 GLuint pathBase,
2011 GLenum fillMode,
2012 GLuint mask,
2013 GLenum coverMode,
2014 GLenum transformType,
2015 const GLfloat *transformValues)
2016{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002017 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002018
2019 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2020 syncRendererState();
2021
2022 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2023 transformType, transformValues);
2024}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002025
Sami Väisänend59ca052016-06-21 16:10:00 +03002026void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2027 GLenum pathNameType,
2028 const void *paths,
2029 GLuint pathBase,
2030 GLint reference,
2031 GLuint mask,
2032 GLenum coverMode,
2033 GLenum transformType,
2034 const GLfloat *transformValues)
2035{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002036 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002037
2038 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2039 syncRendererState();
2040
2041 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2042 transformType, transformValues);
2043}
2044
Sami Väisänen46eaa942016-06-29 10:26:37 +03002045void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2046{
2047 auto *programObject = getProgram(program);
2048
2049 programObject->bindFragmentInputLocation(location, name);
2050}
2051
2052void Context::programPathFragmentInputGen(GLuint program,
2053 GLint location,
2054 GLenum genMode,
2055 GLint components,
2056 const GLfloat *coeffs)
2057{
2058 auto *programObject = getProgram(program);
2059
Jamie Madillbd044ed2017-06-05 12:59:21 -04002060 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002061}
2062
jchen1015015f72017-03-16 13:54:21 +08002063GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2064{
jchen10fd7c3b52017-03-21 15:36:03 +08002065 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002066 return QueryProgramResourceIndex(programObject, programInterface, name);
2067}
2068
jchen10fd7c3b52017-03-21 15:36:03 +08002069void Context::getProgramResourceName(GLuint program,
2070 GLenum programInterface,
2071 GLuint index,
2072 GLsizei bufSize,
2073 GLsizei *length,
2074 GLchar *name)
2075{
2076 const auto *programObject = getProgram(program);
2077 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2078}
2079
jchen10191381f2017-04-11 13:59:04 +08002080GLint Context::getProgramResourceLocation(GLuint program,
2081 GLenum programInterface,
2082 const GLchar *name)
2083{
2084 const auto *programObject = getProgram(program);
2085 return QueryProgramResourceLocation(programObject, programInterface, name);
2086}
2087
jchen10880683b2017-04-12 16:21:55 +08002088void Context::getProgramResourceiv(GLuint program,
2089 GLenum programInterface,
2090 GLuint index,
2091 GLsizei propCount,
2092 const GLenum *props,
2093 GLsizei bufSize,
2094 GLsizei *length,
2095 GLint *params)
2096{
2097 const auto *programObject = getProgram(program);
2098 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2099 length, params);
2100}
2101
jchen10d9cd7b72017-08-30 15:04:25 +08002102void Context::getProgramInterfaceiv(GLuint program,
2103 GLenum programInterface,
2104 GLenum pname,
2105 GLint *params)
2106{
2107 const auto *programObject = getProgram(program);
2108 QueryProgramInterfaceiv(programObject, programInterface, pname, params);
2109}
2110
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002111Error Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002112{
Geoff Langda5777c2014-07-11 09:52:58 -04002113 if (error.isError())
2114 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002115 GLenum code = error.getCode();
2116 mErrors.insert(code);
2117 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2118 {
2119 markContextLost();
2120 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002121
2122 if (!error.getMessage().empty())
2123 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002124 auto *debug = &mGLState.getDebug();
2125 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2126 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002127 }
Geoff Langda5777c2014-07-11 09:52:58 -04002128 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002129
2130 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002131}
2132
2133// Get one of the recorded errors and clear its flag, if any.
2134// [OpenGL ES 2.0.24] section 2.5 page 13.
2135GLenum Context::getError()
2136{
Geoff Langda5777c2014-07-11 09:52:58 -04002137 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002138 {
Geoff Langda5777c2014-07-11 09:52:58 -04002139 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002140 }
Geoff Langda5777c2014-07-11 09:52:58 -04002141 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002142 {
Geoff Langda5777c2014-07-11 09:52:58 -04002143 GLenum error = *mErrors.begin();
2144 mErrors.erase(mErrors.begin());
2145 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002146 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002147}
2148
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002149// NOTE: this function should not assume that this context is current!
2150void Context::markContextLost()
2151{
2152 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002153 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002154 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002155 mContextLostForced = true;
2156 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002157 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002158}
2159
2160bool Context::isContextLost()
2161{
2162 return mContextLost;
2163}
2164
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002165GLenum Context::getResetStatus()
2166{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002167 // Even if the application doesn't want to know about resets, we want to know
2168 // as it will allow us to skip all the calls.
2169 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002170 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002171 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002172 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002173 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002174 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002175
2176 // EXT_robustness, section 2.6: If the reset notification behavior is
2177 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2178 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2179 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002180 }
2181
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002182 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2183 // status should be returned at least once, and GL_NO_ERROR should be returned
2184 // once the device has finished resetting.
2185 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002186 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002187 ASSERT(mResetStatus == GL_NO_ERROR);
2188 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002189
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002190 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002191 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002192 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002193 }
2194 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002195 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002196 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002197 // If markContextLost was used to mark the context lost then
2198 // assume that is not recoverable, and continue to report the
2199 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002200 mResetStatus = mImplementation->getResetStatus();
2201 }
Jamie Madill893ab082014-05-16 16:56:10 -04002202
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002203 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002204}
2205
2206bool Context::isResetNotificationEnabled()
2207{
2208 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2209}
2210
Corentin Walleze3b10e82015-05-20 11:06:25 -04002211const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002212{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002213 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002214}
2215
2216EGLenum Context::getClientType() const
2217{
2218 return mClientType;
2219}
2220
2221EGLenum Context::getRenderBuffer() const
2222{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002223 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2224 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002225 {
2226 return EGL_NONE;
2227 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002228
2229 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2230 ASSERT(backAttachment != nullptr);
2231 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002232}
2233
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002234VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
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 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2238 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002239 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002240 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2241 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002242
Jamie Madill96a483b2017-06-27 16:49:21 -04002243 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002244 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002245
2246 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002247}
2248
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002249TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002250{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002251 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002252 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2253 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002254 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002255 transformFeedback =
2256 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002257 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002258 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002259 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002260
2261 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002262}
2263
2264bool Context::isVertexArrayGenerated(GLuint vertexArray)
2265{
Jamie Madill96a483b2017-06-27 16:49:21 -04002266 ASSERT(mVertexArrayMap.contains(0));
2267 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002268}
2269
2270bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2271{
Jamie Madill96a483b2017-06-27 16:49:21 -04002272 ASSERT(mTransformFeedbackMap.contains(0));
2273 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002274}
2275
Shannon Woods53a94a82014-06-24 15:20:36 -04002276void Context::detachTexture(GLuint texture)
2277{
2278 // Simple pass-through to State's detachTexture method, as textures do not require
2279 // allocation map management either here or in the resource manager at detach time.
2280 // Zero textures are held by the Context, and we don't attempt to request them from
2281 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002282 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002283}
2284
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002285void Context::detachBuffer(GLuint buffer)
2286{
Yuly Novikov5807a532015-12-03 13:01:22 -05002287 // Simple pass-through to State's detachBuffer method, since
2288 // only buffer attachments to container objects that are bound to the current context
2289 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002290
Yuly Novikov5807a532015-12-03 13:01:22 -05002291 // [OpenGL ES 3.2] section 5.1.2 page 45:
2292 // Attachments to unbound container objects, such as
2293 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2294 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002295 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002296}
2297
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002298void Context::detachFramebuffer(GLuint framebuffer)
2299{
Shannon Woods53a94a82014-06-24 15:20:36 -04002300 // Framebuffer detachment is handled by Context, because 0 is a valid
2301 // Framebuffer object, and a pointer to it must be passed from Context
2302 // to State at binding time.
2303
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002304 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002305 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2306 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2307 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002308
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002309 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002310 {
2311 bindReadFramebuffer(0);
2312 }
2313
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002314 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002315 {
2316 bindDrawFramebuffer(0);
2317 }
2318}
2319
2320void Context::detachRenderbuffer(GLuint renderbuffer)
2321{
Jamie Madilla02315b2017-02-23 14:14:47 -05002322 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002323}
2324
Jamie Madill57a89722013-07-02 11:57:03 -04002325void Context::detachVertexArray(GLuint vertexArray)
2326{
Jamie Madill77a72f62015-04-14 11:18:32 -04002327 // Vertex array detachment is handled by Context, because 0 is a valid
2328 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002329 // binding time.
2330
Jamie Madill57a89722013-07-02 11:57:03 -04002331 // [OpenGL ES 3.0.2] section 2.10 page 43:
2332 // If a vertex array object that is currently bound is deleted, the binding
2333 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002334 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002335 {
2336 bindVertexArray(0);
2337 }
2338}
2339
Geoff Langc8058452014-02-03 12:04:11 -05002340void Context::detachTransformFeedback(GLuint transformFeedback)
2341{
Corentin Walleza2257da2016-04-19 16:43:12 -04002342 // Transform feedback detachment is handled by Context, because 0 is a valid
2343 // transform feedback, and a pointer to it must be passed from Context to State at
2344 // binding time.
2345
2346 // The OpenGL specification doesn't mention what should happen when the currently bound
2347 // transform feedback object is deleted. Since it is a container object, we treat it like
2348 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002349 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002350 {
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04002351 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Corentin Walleza2257da2016-04-19 16:43:12 -04002352 }
Geoff Langc8058452014-02-03 12:04:11 -05002353}
2354
Jamie Madilldc356042013-07-19 16:36:57 -04002355void Context::detachSampler(GLuint sampler)
2356{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002357 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002358}
2359
Jamie Madill3ef140a2017-08-26 23:11:21 -04002360void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002361{
Shaodde78e82017-05-22 14:13:27 +08002362 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002363}
2364
Jamie Madille29d1672013-07-19 16:36:57 -04002365void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2366{
Geoff Langc1984ed2016-10-07 12:41:00 -04002367 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002368 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002369 SetSamplerParameteri(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002370 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002371}
Jamie Madille29d1672013-07-19 16:36:57 -04002372
Geoff Langc1984ed2016-10-07 12:41:00 -04002373void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2374{
2375 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002376 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002377 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002378 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002379}
2380
2381void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2382{
Geoff Langc1984ed2016-10-07 12:41:00 -04002383 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002384 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002385 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002386 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002387}
2388
Geoff Langc1984ed2016-10-07 12:41:00 -04002389void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002390{
Geoff Langc1984ed2016-10-07 12:41:00 -04002391 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002392 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002393 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002394 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002395}
2396
Geoff Langc1984ed2016-10-07 12:41:00 -04002397void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002398{
Geoff Langc1984ed2016-10-07 12:41:00 -04002399 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002400 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002401 QuerySamplerParameteriv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002402 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002403}
Jamie Madill9675b802013-07-19 16:36:59 -04002404
Geoff Langc1984ed2016-10-07 12:41:00 -04002405void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2406{
2407 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002408 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002409 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002410 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002411}
2412
Olli Etuahof0fee072016-03-30 15:11:58 +03002413void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2414{
2415 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002416 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002417}
2418
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002419void Context::initRendererString()
2420{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002421 std::ostringstream rendererString;
2422 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002423 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002424 rendererString << ")";
2425
Geoff Langcec35902014-04-16 10:52:36 -04002426 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002427}
2428
Geoff Langc339c4e2016-11-29 10:37:36 -05002429void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002430{
Geoff Langc339c4e2016-11-29 10:37:36 -05002431 const Version &clientVersion = getClientVersion();
2432
2433 std::ostringstream versionString;
2434 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2435 << ANGLE_VERSION_STRING << ")";
2436 mVersionString = MakeStaticString(versionString.str());
2437
2438 std::ostringstream shadingLanguageVersionString;
2439 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2440 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2441 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2442 << ")";
2443 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002444}
2445
Geoff Langcec35902014-04-16 10:52:36 -04002446void Context::initExtensionStrings()
2447{
Geoff Langc339c4e2016-11-29 10:37:36 -05002448 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2449 std::ostringstream combinedStringStream;
2450 std::copy(strings.begin(), strings.end(),
2451 std::ostream_iterator<const char *>(combinedStringStream, " "));
2452 return MakeStaticString(combinedStringStream.str());
2453 };
2454
2455 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002456 for (const auto &extensionString : mExtensions.getStrings())
2457 {
2458 mExtensionStrings.push_back(MakeStaticString(extensionString));
2459 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002460 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002461
Bryan Bernhart58806562017-01-05 13:09:31 -08002462 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2463
Geoff Langc339c4e2016-11-29 10:37:36 -05002464 mRequestableExtensionStrings.clear();
2465 for (const auto &extensionInfo : GetExtensionInfoMap())
2466 {
2467 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002468 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2469 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002470 {
2471 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2472 }
2473 }
2474 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002475}
2476
Geoff Langc339c4e2016-11-29 10:37:36 -05002477const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002478{
Geoff Langc339c4e2016-11-29 10:37:36 -05002479 switch (name)
2480 {
2481 case GL_VENDOR:
2482 return reinterpret_cast<const GLubyte *>("Google Inc.");
2483
2484 case GL_RENDERER:
2485 return reinterpret_cast<const GLubyte *>(mRendererString);
2486
2487 case GL_VERSION:
2488 return reinterpret_cast<const GLubyte *>(mVersionString);
2489
2490 case GL_SHADING_LANGUAGE_VERSION:
2491 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2492
2493 case GL_EXTENSIONS:
2494 return reinterpret_cast<const GLubyte *>(mExtensionString);
2495
2496 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2497 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2498
2499 default:
2500 UNREACHABLE();
2501 return nullptr;
2502 }
Geoff Langcec35902014-04-16 10:52:36 -04002503}
2504
Geoff Langc339c4e2016-11-29 10:37:36 -05002505const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002506{
Geoff Langc339c4e2016-11-29 10:37:36 -05002507 switch (name)
2508 {
2509 case GL_EXTENSIONS:
2510 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2511
2512 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2513 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2514
2515 default:
2516 UNREACHABLE();
2517 return nullptr;
2518 }
Geoff Langcec35902014-04-16 10:52:36 -04002519}
2520
2521size_t Context::getExtensionStringCount() const
2522{
2523 return mExtensionStrings.size();
2524}
2525
Geoff Langc339c4e2016-11-29 10:37:36 -05002526void Context::requestExtension(const char *name)
2527{
2528 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2529 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2530 const auto &extension = extensionInfos.at(name);
2531 ASSERT(extension.Requestable);
2532
2533 if (mExtensions.*(extension.ExtensionsMember))
2534 {
2535 // Extension already enabled
2536 return;
2537 }
2538
2539 mExtensions.*(extension.ExtensionsMember) = true;
2540 updateCaps();
2541 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002542
Jamie Madill2f348d22017-06-05 10:50:59 -04002543 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2544 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002545
Jamie Madill81c2e252017-09-09 23:32:46 -04002546 // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
2547 // sampleable.
2548 mState.mTextures->signalAllTexturesDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002549 for (auto &zeroTexture : mZeroTextures)
2550 {
Jamie Madill81c2e252017-09-09 23:32:46 -04002551 zeroTexture.second->signalDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002552 }
2553
2554 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002555}
2556
2557size_t Context::getRequestableExtensionStringCount() const
2558{
2559 return mRequestableExtensionStrings.size();
2560}
2561
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002562void Context::beginTransformFeedback(GLenum primitiveMode)
2563{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002564 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002565 ASSERT(transformFeedback != nullptr);
2566 ASSERT(!transformFeedback->isPaused());
2567
Jamie Madill6c1f6712017-02-14 19:08:04 -05002568 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002569}
2570
2571bool Context::hasActiveTransformFeedback(GLuint program) const
2572{
2573 for (auto pair : mTransformFeedbackMap)
2574 {
2575 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2576 {
2577 return true;
2578 }
2579 }
2580 return false;
2581}
2582
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002583void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002584{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002585 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002586
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002587 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002588
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002589 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002590
Geoff Langeb66a6e2016-10-31 13:06:12 -04002591 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002592 {
2593 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002594 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002595 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002596 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002597 mExtensions.multiview = false;
2598 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002599 }
2600
Geoff Langeb66a6e2016-10-31 13:06:12 -04002601 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002602 {
2603 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002604 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002605 }
2606
Jamie Madill00ed7a12016-05-19 13:13:38 -04002607 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002608 mExtensions.bindUniformLocation = true;
2609 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002610 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002611 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002612 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002613
2614 // Enable the no error extension if the context was created with the flag.
2615 mExtensions.noError = mSkipValidation;
2616
Corentin Wallezccab69d2017-01-27 16:57:15 -05002617 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002618 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002619
Geoff Lang70d0f492015-12-10 17:45:46 -05002620 // Explicitly enable GL_KHR_debug
2621 mExtensions.debug = true;
2622 mExtensions.maxDebugMessageLength = 1024;
2623 mExtensions.maxDebugLoggedMessages = 1024;
2624 mExtensions.maxDebugGroupStackDepth = 1024;
2625 mExtensions.maxLabelLength = 1024;
2626
Geoff Langff5b2d52016-09-07 11:32:23 -04002627 // Explicitly enable GL_ANGLE_robust_client_memory
2628 mExtensions.robustClientMemory = true;
2629
Jamie Madille08a1d32017-03-07 17:24:06 -05002630 // Determine robust resource init availability from EGL.
2631 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002632 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002633
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08002634 // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
2635 // supports it.
2636 mExtensions.robustBufferAccessBehavior =
2637 mRobustAccess && mExtensions.robustBufferAccessBehavior;
2638
Jamie Madillc43be722017-07-13 16:22:14 -04002639 // Enable the cache control query unconditionally.
2640 mExtensions.programCacheControl = true;
2641
Geoff Lang301d1612014-07-09 10:34:37 -04002642 // Apply implementation limits
2643 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002644 mCaps.maxVertexAttribBindings =
2645 getClientVersion() < ES_3_1
2646 ? mCaps.maxVertexAttributes
2647 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2648
Jamie Madill231c7f52017-04-26 13:45:37 -04002649 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2650 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2651 mCaps.maxVertexOutputComponents =
2652 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002653
Jamie Madill231c7f52017-04-26 13:45:37 -04002654 mCaps.maxFragmentInputComponents =
2655 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002656
Geoff Langc287ea62016-09-16 14:46:51 -04002657 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002658 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002659 for (const auto &extensionInfo : GetExtensionInfoMap())
2660 {
2661 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002662 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002663 {
2664 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2665 }
2666 }
2667
2668 // Generate texture caps
2669 updateCaps();
2670}
2671
2672void Context::updateCaps()
2673{
Geoff Lang900013c2014-07-07 11:32:19 -04002674 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002675 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002676
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002677 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002678 {
Geoff Langca271392017-04-05 12:30:00 -04002679 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002680 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002681
Geoff Langca271392017-04-05 12:30:00 -04002682 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002683
Geoff Lang0d8b7242015-09-09 14:56:53 -04002684 // Update the format caps based on the client version and extensions.
2685 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2686 // ES3.
2687 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002688 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002689 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002690 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002691 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002692 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002693
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002694 // OpenGL ES does not support multisampling with non-rendererable formats
2695 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002696 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002697 (getClientVersion() < ES_3_1 &&
2698 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002699 {
Geoff Langd87878e2014-09-19 15:42:59 -04002700 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002701 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002702 else
2703 {
2704 // We may have limited the max samples for some required renderbuffer formats due to
2705 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2706 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2707
2708 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2709 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2710 // exception of signed and unsigned integer formats."
2711 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2712 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2713 {
2714 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2715 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2716 }
2717
2718 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2719 if (getClientVersion() >= ES_3_1)
2720 {
2721 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2722 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2723 // the exception that the signed and unsigned integer formats are required only to
2724 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2725 // multisamples, which must be at least one."
2726 if (formatInfo.componentType == GL_INT ||
2727 formatInfo.componentType == GL_UNSIGNED_INT)
2728 {
2729 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2730 }
2731
2732 // GLES 3.1 section 19.3.1.
2733 if (formatCaps.texturable)
2734 {
2735 if (formatInfo.depthBits > 0)
2736 {
2737 mCaps.maxDepthTextureSamples =
2738 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2739 }
2740 else if (formatInfo.redBits > 0)
2741 {
2742 mCaps.maxColorTextureSamples =
2743 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2744 }
2745 }
2746 }
2747 }
Geoff Langd87878e2014-09-19 15:42:59 -04002748
2749 if (formatCaps.texturable && formatInfo.compressed)
2750 {
Geoff Langca271392017-04-05 12:30:00 -04002751 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002752 }
2753
Geoff Langca271392017-04-05 12:30:00 -04002754 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002755 }
Jamie Madill32447362017-06-28 14:53:52 -04002756
2757 // If program binary is disabled, blank out the memory cache pointer.
2758 if (!mImplementation->getNativeExtensions().getProgramBinary)
2759 {
2760 mMemoryProgramCache = nullptr;
2761 }
Geoff Lang493daf52014-07-03 13:38:44 -04002762}
2763
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002764void Context::initWorkarounds()
2765{
Jamie Madill761b02c2017-06-23 16:27:06 -04002766 // Apply back-end workarounds.
2767 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2768
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002769 // Lose the context upon out of memory error if the application is
2770 // expecting to watch for those events.
2771 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2772}
2773
Jamie Madill1b94d432015-08-07 13:23:23 -04002774void Context::syncRendererState()
2775{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002776 mGLState.syncDirtyObjects(this);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002777 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002778 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002779 mGLState.clearDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -04002780}
2781
Jamie Madillad9f24e2016-02-12 09:27:24 -05002782void Context::syncRendererState(const State::DirtyBits &bitMask,
2783 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002784{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002785 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002786 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002787 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002788 mGLState.clearDirtyBits(dirtyBits);
Jamie Madill1b94d432015-08-07 13:23:23 -04002789}
Jamie Madillc29968b2016-01-20 11:17:23 -05002790
2791void Context::blitFramebuffer(GLint srcX0,
2792 GLint srcY0,
2793 GLint srcX1,
2794 GLint srcY1,
2795 GLint dstX0,
2796 GLint dstY0,
2797 GLint dstX1,
2798 GLint dstY1,
2799 GLbitfield mask,
2800 GLenum filter)
2801{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002802 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002803 ASSERT(drawFramebuffer);
2804
2805 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2806 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2807
Jamie Madillad9f24e2016-02-12 09:27:24 -05002808 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002809
Jamie Madillc564c072017-06-01 12:45:42 -04002810 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002811}
Jamie Madillc29968b2016-01-20 11:17:23 -05002812
2813void Context::clear(GLbitfield mask)
2814{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002815 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002816 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002817}
2818
2819void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2820{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002821 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002822 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002823}
2824
2825void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2826{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002827 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002828 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002829}
2830
2831void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2832{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002833 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002834 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002835}
2836
2837void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2838{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002839 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002840 ASSERT(framebufferObject);
2841
2842 // If a buffer is not present, the clear has no effect
2843 if (framebufferObject->getDepthbuffer() == nullptr &&
2844 framebufferObject->getStencilbuffer() == nullptr)
2845 {
2846 return;
2847 }
2848
Jamie Madillad9f24e2016-02-12 09:27:24 -05002849 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002850 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002851}
2852
2853void Context::readPixels(GLint x,
2854 GLint y,
2855 GLsizei width,
2856 GLsizei height,
2857 GLenum format,
2858 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002859 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002860{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002861 if (width == 0 || height == 0)
2862 {
2863 return;
2864 }
2865
Jamie Madillad9f24e2016-02-12 09:27:24 -05002866 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002867
Jamie Madillb6664922017-07-25 12:55:04 -04002868 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2869 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002870
2871 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002872 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002873}
2874
2875void Context::copyTexImage2D(GLenum target,
2876 GLint level,
2877 GLenum internalformat,
2878 GLint x,
2879 GLint y,
2880 GLsizei width,
2881 GLsizei height,
2882 GLint border)
2883{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002884 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002885 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002886
Jamie Madillc29968b2016-01-20 11:17:23 -05002887 Rectangle sourceArea(x, y, width, height);
2888
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002889 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002890 Texture *texture =
2891 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002892 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002893}
2894
2895void Context::copyTexSubImage2D(GLenum target,
2896 GLint level,
2897 GLint xoffset,
2898 GLint yoffset,
2899 GLint x,
2900 GLint y,
2901 GLsizei width,
2902 GLsizei height)
2903{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002904 if (width == 0 || height == 0)
2905 {
2906 return;
2907 }
2908
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002909 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002910 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002911
Jamie Madillc29968b2016-01-20 11:17:23 -05002912 Offset destOffset(xoffset, yoffset, 0);
2913 Rectangle sourceArea(x, y, width, height);
2914
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002915 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002916 Texture *texture =
2917 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002918 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002919}
2920
2921void Context::copyTexSubImage3D(GLenum target,
2922 GLint level,
2923 GLint xoffset,
2924 GLint yoffset,
2925 GLint zoffset,
2926 GLint x,
2927 GLint y,
2928 GLsizei width,
2929 GLsizei height)
2930{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002931 if (width == 0 || height == 0)
2932 {
2933 return;
2934 }
2935
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002936 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002937 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002938
Jamie Madillc29968b2016-01-20 11:17:23 -05002939 Offset destOffset(xoffset, yoffset, zoffset);
2940 Rectangle sourceArea(x, y, width, height);
2941
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002942 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002943 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002944 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002945}
2946
2947void Context::framebufferTexture2D(GLenum target,
2948 GLenum attachment,
2949 GLenum textarget,
2950 GLuint texture,
2951 GLint level)
2952{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002953 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002954 ASSERT(framebuffer);
2955
2956 if (texture != 0)
2957 {
2958 Texture *textureObj = getTexture(texture);
2959
2960 ImageIndex index = ImageIndex::MakeInvalid();
2961
2962 if (textarget == GL_TEXTURE_2D)
2963 {
2964 index = ImageIndex::Make2D(level);
2965 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002966 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
2967 {
2968 index = ImageIndex::MakeRectangle(level);
2969 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002970 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2971 {
2972 ASSERT(level == 0);
2973 index = ImageIndex::Make2DMultisample();
2974 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002975 else
2976 {
2977 ASSERT(IsCubeMapTextureTarget(textarget));
2978 index = ImageIndex::MakeCube(textarget, level);
2979 }
2980
Jamie Madilla02315b2017-02-23 14:14:47 -05002981 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002982 }
2983 else
2984 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002985 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002986 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002987
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002988 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002989}
2990
2991void Context::framebufferRenderbuffer(GLenum target,
2992 GLenum attachment,
2993 GLenum renderbuffertarget,
2994 GLuint renderbuffer)
2995{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002996 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002997 ASSERT(framebuffer);
2998
2999 if (renderbuffer != 0)
3000 {
3001 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003002
3003 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003004 renderbufferObject);
3005 }
3006 else
3007 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003008 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003009 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003010
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003011 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003012}
3013
3014void Context::framebufferTextureLayer(GLenum target,
3015 GLenum attachment,
3016 GLuint texture,
3017 GLint level,
3018 GLint layer)
3019{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003020 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003021 ASSERT(framebuffer);
3022
3023 if (texture != 0)
3024 {
3025 Texture *textureObject = getTexture(texture);
3026
3027 ImageIndex index = ImageIndex::MakeInvalid();
3028
3029 if (textureObject->getTarget() == GL_TEXTURE_3D)
3030 {
3031 index = ImageIndex::Make3D(level, layer);
3032 }
3033 else
3034 {
3035 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3036 index = ImageIndex::Make2DArray(level, layer);
3037 }
3038
Jamie Madilla02315b2017-02-23 14:14:47 -05003039 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003040 }
3041 else
3042 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003043 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003044 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003045
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003046 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003047}
3048
Martin Radev137032d2017-07-13 10:11:12 +03003049void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3050 GLenum attachment,
3051 GLuint texture,
3052 GLint level,
3053 GLint baseViewIndex,
3054 GLsizei numViews)
3055{
Martin Radev82ef7742017-08-08 17:44:58 +03003056 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3057 ASSERT(framebuffer);
3058
3059 if (texture != 0)
3060 {
3061 Texture *textureObj = getTexture(texture);
3062
Martin Radev18b75ba2017-08-15 15:50:40 +03003063 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003064 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3065 numViews, baseViewIndex);
3066 }
3067 else
3068 {
3069 framebuffer->resetAttachment(this, attachment);
3070 }
3071
3072 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003073}
3074
3075void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3076 GLenum attachment,
3077 GLuint texture,
3078 GLint level,
3079 GLsizei numViews,
3080 const GLint *viewportOffsets)
3081{
Martin Radev5dae57b2017-07-14 16:15:55 +03003082 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3083 ASSERT(framebuffer);
3084
3085 if (texture != 0)
3086 {
3087 Texture *textureObj = getTexture(texture);
3088
3089 ImageIndex index = ImageIndex::Make2D(level);
3090 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3091 textureObj, numViews, viewportOffsets);
3092 }
3093 else
3094 {
3095 framebuffer->resetAttachment(this, attachment);
3096 }
3097
3098 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003099}
3100
Jamie Madillc29968b2016-01-20 11:17:23 -05003101void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3102{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003103 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003104 ASSERT(framebuffer);
3105 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003106 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003107}
3108
3109void Context::readBuffer(GLenum mode)
3110{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003111 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003112 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003113 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003114}
3115
3116void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3117{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003118 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003119 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003120
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003121 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003122 ASSERT(framebuffer);
3123
3124 // The specification isn't clear what should be done when the framebuffer isn't complete.
3125 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003126 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003127}
3128
3129void Context::invalidateFramebuffer(GLenum target,
3130 GLsizei numAttachments,
3131 const GLenum *attachments)
3132{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003133 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003134 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003135
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003136 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003137 ASSERT(framebuffer);
3138
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003139 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003140 {
Jamie Madill437fa652016-05-03 15:13:24 -04003141 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003142 }
Jamie Madill437fa652016-05-03 15:13:24 -04003143
Jamie Madill4928b7c2017-06-20 12:57:39 -04003144 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003145}
3146
3147void Context::invalidateSubFramebuffer(GLenum target,
3148 GLsizei numAttachments,
3149 const GLenum *attachments,
3150 GLint x,
3151 GLint y,
3152 GLsizei width,
3153 GLsizei height)
3154{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003155 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003156 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003157
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003158 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003159 ASSERT(framebuffer);
3160
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003161 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003162 {
Jamie Madill437fa652016-05-03 15:13:24 -04003163 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003164 }
Jamie Madill437fa652016-05-03 15:13:24 -04003165
3166 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003167 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003168}
3169
Jamie Madill73a84962016-02-12 09:27:23 -05003170void Context::texImage2D(GLenum target,
3171 GLint level,
3172 GLint internalformat,
3173 GLsizei width,
3174 GLsizei height,
3175 GLint border,
3176 GLenum format,
3177 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003178 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003179{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003180 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003181
3182 Extents size(width, height, 1);
3183 Texture *texture =
3184 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003185 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3186 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003187}
3188
3189void Context::texImage3D(GLenum target,
3190 GLint level,
3191 GLint internalformat,
3192 GLsizei width,
3193 GLsizei height,
3194 GLsizei depth,
3195 GLint border,
3196 GLenum format,
3197 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003198 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003199{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003200 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003201
3202 Extents size(width, height, depth);
3203 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003204 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3205 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003206}
3207
3208void Context::texSubImage2D(GLenum target,
3209 GLint level,
3210 GLint xoffset,
3211 GLint yoffset,
3212 GLsizei width,
3213 GLsizei height,
3214 GLenum format,
3215 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003216 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003217{
3218 // Zero sized uploads are valid but no-ops
3219 if (width == 0 || height == 0)
3220 {
3221 return;
3222 }
3223
Jamie Madillad9f24e2016-02-12 09:27:24 -05003224 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003225
3226 Box area(xoffset, yoffset, 0, width, height, 1);
3227 Texture *texture =
3228 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003229 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3230 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003231}
3232
3233void Context::texSubImage3D(GLenum target,
3234 GLint level,
3235 GLint xoffset,
3236 GLint yoffset,
3237 GLint zoffset,
3238 GLsizei width,
3239 GLsizei height,
3240 GLsizei depth,
3241 GLenum format,
3242 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003243 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003244{
3245 // Zero sized uploads are valid but no-ops
3246 if (width == 0 || height == 0 || depth == 0)
3247 {
3248 return;
3249 }
3250
Jamie Madillad9f24e2016-02-12 09:27:24 -05003251 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003252
3253 Box area(xoffset, yoffset, zoffset, width, height, depth);
3254 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003255 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3256 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003257}
3258
3259void Context::compressedTexImage2D(GLenum target,
3260 GLint level,
3261 GLenum internalformat,
3262 GLsizei width,
3263 GLsizei height,
3264 GLint border,
3265 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003266 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003267{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003268 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003269
3270 Extents size(width, height, 1);
3271 Texture *texture =
3272 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003273 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003274 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003275 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003276}
3277
3278void Context::compressedTexImage3D(GLenum target,
3279 GLint level,
3280 GLenum internalformat,
3281 GLsizei width,
3282 GLsizei height,
3283 GLsizei depth,
3284 GLint border,
3285 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003286 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003287{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003288 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003289
3290 Extents size(width, height, depth);
3291 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003292 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003293 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003294 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003295}
3296
3297void Context::compressedTexSubImage2D(GLenum target,
3298 GLint level,
3299 GLint xoffset,
3300 GLint yoffset,
3301 GLsizei width,
3302 GLsizei height,
3303 GLenum format,
3304 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003305 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003306{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003307 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003308
3309 Box area(xoffset, yoffset, 0, width, height, 1);
3310 Texture *texture =
3311 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003312 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003313 format, imageSize,
3314 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003315}
3316
3317void Context::compressedTexSubImage3D(GLenum target,
3318 GLint level,
3319 GLint xoffset,
3320 GLint yoffset,
3321 GLint zoffset,
3322 GLsizei width,
3323 GLsizei height,
3324 GLsizei depth,
3325 GLenum format,
3326 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003327 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003328{
3329 // Zero sized uploads are valid but no-ops
3330 if (width == 0 || height == 0)
3331 {
3332 return;
3333 }
3334
Jamie Madillad9f24e2016-02-12 09:27:24 -05003335 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003336
3337 Box area(xoffset, yoffset, zoffset, width, height, depth);
3338 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003339 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003340 format, imageSize,
3341 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003342}
3343
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003344void Context::generateMipmap(GLenum target)
3345{
3346 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003347 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003348}
3349
Geoff Lang97073d12016-04-20 10:42:34 -07003350void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003351 GLint sourceLevel,
3352 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003353 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003354 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003355 GLint internalFormat,
3356 GLenum destType,
3357 GLboolean unpackFlipY,
3358 GLboolean unpackPremultiplyAlpha,
3359 GLboolean unpackUnmultiplyAlpha)
3360{
3361 syncStateForTexImage();
3362
3363 gl::Texture *sourceTexture = getTexture(sourceId);
3364 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003365 handleError(destTexture->copyTexture(
3366 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3367 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003368}
3369
3370void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003371 GLint sourceLevel,
3372 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003373 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003374 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003375 GLint xoffset,
3376 GLint yoffset,
3377 GLint x,
3378 GLint y,
3379 GLsizei width,
3380 GLsizei height,
3381 GLboolean unpackFlipY,
3382 GLboolean unpackPremultiplyAlpha,
3383 GLboolean unpackUnmultiplyAlpha)
3384{
3385 // Zero sized copies are valid but no-ops
3386 if (width == 0 || height == 0)
3387 {
3388 return;
3389 }
3390
3391 syncStateForTexImage();
3392
3393 gl::Texture *sourceTexture = getTexture(sourceId);
3394 gl::Texture *destTexture = getTexture(destId);
3395 Offset offset(xoffset, yoffset, 0);
3396 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003397 handleError(destTexture->copySubTexture(
3398 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3399 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003400}
3401
Geoff Lang47110bf2016-04-20 11:13:22 -07003402void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3403{
3404 syncStateForTexImage();
3405
3406 gl::Texture *sourceTexture = getTexture(sourceId);
3407 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003408 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003409}
3410
Geoff Lang496c02d2016-10-20 11:38:11 -07003411void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003412{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003414 ASSERT(buffer);
3415
Geoff Lang496c02d2016-10-20 11:38:11 -07003416 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003417}
3418
Jamie Madill876429b2017-04-20 15:46:24 -04003419void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003420{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003421 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003422 ASSERT(buffer);
3423
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003424 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003425 if (error.isError())
3426 {
Jamie Madill437fa652016-05-03 15:13:24 -04003427 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003428 return nullptr;
3429 }
3430
3431 return buffer->getMapPointer();
3432}
3433
3434GLboolean Context::unmapBuffer(GLenum target)
3435{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003436 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003437 ASSERT(buffer);
3438
3439 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003440 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003441 if (error.isError())
3442 {
Jamie Madill437fa652016-05-03 15:13:24 -04003443 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003444 return GL_FALSE;
3445 }
3446
3447 return result;
3448}
3449
Jamie Madill876429b2017-04-20 15:46:24 -04003450void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003451{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003452 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003453 ASSERT(buffer);
3454
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003455 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003456 if (error.isError())
3457 {
Jamie Madill437fa652016-05-03 15:13:24 -04003458 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003459 return nullptr;
3460 }
3461
3462 return buffer->getMapPointer();
3463}
3464
3465void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3466{
3467 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3468}
3469
Jamie Madillad9f24e2016-02-12 09:27:24 -05003470void Context::syncStateForReadPixels()
3471{
3472 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3473}
3474
3475void Context::syncStateForTexImage()
3476{
3477 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3478}
3479
3480void Context::syncStateForClear()
3481{
3482 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3483}
3484
3485void Context::syncStateForBlit()
3486{
3487 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3488}
3489
Jamie Madillc20ab272016-06-09 07:20:46 -07003490void Context::activeTexture(GLenum texture)
3491{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003492 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003493}
3494
Jamie Madill876429b2017-04-20 15:46:24 -04003495void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003496{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003497 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003498}
3499
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003500void Context::blendEquation(GLenum mode)
3501{
3502 mGLState.setBlendEquation(mode, mode);
3503}
3504
Jamie Madillc20ab272016-06-09 07:20:46 -07003505void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3506{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003507 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003508}
3509
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003510void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3511{
3512 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3513}
3514
Jamie Madillc20ab272016-06-09 07:20:46 -07003515void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3516{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003517 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003518}
3519
Jamie Madill876429b2017-04-20 15:46:24 -04003520void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003521{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003522 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003523}
3524
Jamie Madill876429b2017-04-20 15:46:24 -04003525void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003526{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003527 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003528}
3529
3530void Context::clearStencil(GLint s)
3531{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003532 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003533}
3534
3535void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003538}
3539
3540void Context::cullFace(GLenum mode)
3541{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003542 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003543}
3544
3545void Context::depthFunc(GLenum func)
3546{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003547 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003548}
3549
3550void Context::depthMask(GLboolean flag)
3551{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003552 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003553}
3554
Jamie Madill876429b2017-04-20 15:46:24 -04003555void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003556{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003557 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003558}
3559
3560void Context::disable(GLenum cap)
3561{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003562 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003563}
3564
3565void Context::disableVertexAttribArray(GLuint index)
3566{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003567 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003568}
3569
3570void Context::enable(GLenum cap)
3571{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003572 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003573}
3574
3575void Context::enableVertexAttribArray(GLuint index)
3576{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003577 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003578}
3579
3580void Context::frontFace(GLenum mode)
3581{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003582 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003583}
3584
3585void Context::hint(GLenum target, GLenum mode)
3586{
3587 switch (target)
3588 {
3589 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003590 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003591 break;
3592
3593 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003594 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003595 break;
3596
3597 default:
3598 UNREACHABLE();
3599 return;
3600 }
3601}
3602
3603void Context::lineWidth(GLfloat width)
3604{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003605 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003606}
3607
3608void Context::pixelStorei(GLenum pname, GLint param)
3609{
3610 switch (pname)
3611 {
3612 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003613 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003614 break;
3615
3616 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003617 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003618 break;
3619
3620 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003621 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003622 break;
3623
3624 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003625 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003626 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003627 break;
3628
3629 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003630 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003631 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003632 break;
3633
3634 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003635 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003636 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003637 break;
3638
3639 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003640 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003641 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003642 break;
3643
3644 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003645 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003646 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003647 break;
3648
3649 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003650 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003651 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003652 break;
3653
3654 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003655 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003656 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003657 break;
3658
3659 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003660 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003661 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003662 break;
3663
3664 default:
3665 UNREACHABLE();
3666 return;
3667 }
3668}
3669
3670void Context::polygonOffset(GLfloat factor, GLfloat units)
3671{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003672 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003673}
3674
Jamie Madill876429b2017-04-20 15:46:24 -04003675void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003676{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003677 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003678}
3679
3680void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3681{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003682 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003683}
3684
3685void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3686{
3687 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3688 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003689 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003690 }
3691
3692 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3693 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003694 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003695 }
3696}
3697
3698void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3699{
3700 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3701 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003702 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003703 }
3704
3705 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3706 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003707 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003708 }
3709}
3710
3711void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3712{
3713 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3714 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003715 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003716 }
3717
3718 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3719 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003720 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003721 }
3722}
3723
3724void Context::vertexAttrib1f(GLuint index, GLfloat x)
3725{
3726 GLfloat vals[4] = {x, 0, 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::vertexAttrib1fv(GLuint index, const GLfloat *values)
3731{
3732 GLfloat vals[4] = {values[0], 0, 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::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3737{
3738 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003739 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003740}
3741
3742void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3743{
3744 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003745 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003746}
3747
3748void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3749{
3750 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003751 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003752}
3753
3754void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3755{
3756 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003757 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003758}
3759
3760void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3761{
3762 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003763 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003764}
3765
3766void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3767{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003768 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003769}
3770
3771void Context::vertexAttribPointer(GLuint index,
3772 GLint size,
3773 GLenum type,
3774 GLboolean normalized,
3775 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003776 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003777{
Shaodde78e82017-05-22 14:13:27 +08003778 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3779 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003780}
3781
Shao80957d92017-02-20 21:25:59 +08003782void Context::vertexAttribFormat(GLuint attribIndex,
3783 GLint size,
3784 GLenum type,
3785 GLboolean normalized,
3786 GLuint relativeOffset)
3787{
3788 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3789 relativeOffset);
3790}
3791
3792void Context::vertexAttribIFormat(GLuint attribIndex,
3793 GLint size,
3794 GLenum type,
3795 GLuint relativeOffset)
3796{
3797 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3798}
3799
3800void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3801{
Shaodde78e82017-05-22 14:13:27 +08003802 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003803}
3804
3805void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3806{
3807 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3808}
3809
Jamie Madillc20ab272016-06-09 07:20:46 -07003810void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3811{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003812 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003813}
3814
3815void Context::vertexAttribIPointer(GLuint index,
3816 GLint size,
3817 GLenum type,
3818 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003819 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003820{
Shaodde78e82017-05-22 14:13:27 +08003821 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3822 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003823}
3824
3825void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3826{
3827 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003828 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003829}
3830
3831void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3832{
3833 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003834 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003835}
3836
3837void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3838{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003839 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003840}
3841
3842void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3843{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003844 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003845}
3846
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003847void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3848{
3849 const VertexAttribCurrentValueData &currentValues =
3850 getGLState().getVertexAttribCurrentValue(index);
3851 const VertexArray *vao = getGLState().getVertexArray();
3852 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3853 currentValues, pname, params);
3854}
3855
3856void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3857{
3858 const VertexAttribCurrentValueData &currentValues =
3859 getGLState().getVertexAttribCurrentValue(index);
3860 const VertexArray *vao = getGLState().getVertexArray();
3861 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3862 currentValues, pname, params);
3863}
3864
3865void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3866{
3867 const VertexAttribCurrentValueData &currentValues =
3868 getGLState().getVertexAttribCurrentValue(index);
3869 const VertexArray *vao = getGLState().getVertexArray();
3870 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3871 currentValues, pname, params);
3872}
3873
3874void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3875{
3876 const VertexAttribCurrentValueData &currentValues =
3877 getGLState().getVertexAttribCurrentValue(index);
3878 const VertexArray *vao = getGLState().getVertexArray();
3879 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3880 currentValues, pname, params);
3881}
3882
Jamie Madill876429b2017-04-20 15:46:24 -04003883void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003884{
3885 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3886 QueryVertexAttribPointerv(attrib, pname, pointer);
3887}
3888
Jamie Madillc20ab272016-06-09 07:20:46 -07003889void Context::debugMessageControl(GLenum source,
3890 GLenum type,
3891 GLenum severity,
3892 GLsizei count,
3893 const GLuint *ids,
3894 GLboolean enabled)
3895{
3896 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003897 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3898 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003899}
3900
3901void Context::debugMessageInsert(GLenum source,
3902 GLenum type,
3903 GLuint id,
3904 GLenum severity,
3905 GLsizei length,
3906 const GLchar *buf)
3907{
3908 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003909 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003910}
3911
3912void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3913{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003914 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003915}
3916
3917GLuint Context::getDebugMessageLog(GLuint count,
3918 GLsizei bufSize,
3919 GLenum *sources,
3920 GLenum *types,
3921 GLuint *ids,
3922 GLenum *severities,
3923 GLsizei *lengths,
3924 GLchar *messageLog)
3925{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003926 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3927 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003928}
3929
3930void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3931{
3932 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003933 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003934}
3935
3936void Context::popDebugGroup()
3937{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003938 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003939}
3940
Jamie Madill876429b2017-04-20 15:46:24 -04003941void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003942{
3943 Buffer *buffer = mGLState.getTargetBuffer(target);
3944 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003945 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003946}
3947
Jamie Madill876429b2017-04-20 15:46:24 -04003948void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003949{
3950 if (data == nullptr)
3951 {
3952 return;
3953 }
3954
3955 Buffer *buffer = mGLState.getTargetBuffer(target);
3956 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003957 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003958}
3959
Jamie Madillef300b12016-10-07 15:12:09 -04003960void Context::attachShader(GLuint program, GLuint shader)
3961{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003962 auto programObject = mState.mShaderPrograms->getProgram(program);
3963 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003964 ASSERT(programObject && shaderObject);
3965 programObject->attachShader(shaderObject);
3966}
3967
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003968const Workarounds &Context::getWorkarounds() const
3969{
3970 return mWorkarounds;
3971}
3972
Jamie Madillb0817d12016-11-01 15:48:31 -04003973void Context::copyBufferSubData(GLenum readTarget,
3974 GLenum writeTarget,
3975 GLintptr readOffset,
3976 GLintptr writeOffset,
3977 GLsizeiptr size)
3978{
3979 // if size is zero, the copy is a successful no-op
3980 if (size == 0)
3981 {
3982 return;
3983 }
3984
3985 // TODO(jmadill): cache these.
3986 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3987 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3988
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003989 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003990}
3991
Jamie Madill01a80ee2016-11-07 12:06:18 -05003992void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3993{
3994 Program *programObject = getProgram(program);
3995 // TODO(jmadill): Re-use this from the validation if possible.
3996 ASSERT(programObject);
3997 programObject->bindAttributeLocation(index, name);
3998}
3999
4000void Context::bindBuffer(GLenum target, GLuint buffer)
4001{
4002 switch (target)
4003 {
4004 case GL_ARRAY_BUFFER:
4005 bindArrayBuffer(buffer);
4006 break;
4007 case GL_ELEMENT_ARRAY_BUFFER:
4008 bindElementArrayBuffer(buffer);
4009 break;
4010 case GL_COPY_READ_BUFFER:
4011 bindCopyReadBuffer(buffer);
4012 break;
4013 case GL_COPY_WRITE_BUFFER:
4014 bindCopyWriteBuffer(buffer);
4015 break;
4016 case GL_PIXEL_PACK_BUFFER:
4017 bindPixelPackBuffer(buffer);
4018 break;
4019 case GL_PIXEL_UNPACK_BUFFER:
4020 bindPixelUnpackBuffer(buffer);
4021 break;
4022 case GL_UNIFORM_BUFFER:
4023 bindGenericUniformBuffer(buffer);
4024 break;
4025 case GL_TRANSFORM_FEEDBACK_BUFFER:
4026 bindGenericTransformFeedbackBuffer(buffer);
4027 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004028 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004029 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004030 break;
4031 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004032 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004033 break;
4034 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004035 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004036 break;
4037 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004038 if (buffer != 0)
4039 {
4040 // Binding buffers to this binding point is not implemented yet.
4041 UNIMPLEMENTED();
4042 }
Geoff Lang3b573612016-10-31 14:08:10 -04004043 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004044
4045 default:
4046 UNREACHABLE();
4047 break;
4048 }
4049}
4050
Jiajia Qin6eafb042016-12-27 17:04:07 +08004051void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4052{
4053 bindBufferRange(target, index, buffer, 0, 0);
4054}
4055
4056void Context::bindBufferRange(GLenum target,
4057 GLuint index,
4058 GLuint buffer,
4059 GLintptr offset,
4060 GLsizeiptr size)
4061{
4062 switch (target)
4063 {
4064 case GL_TRANSFORM_FEEDBACK_BUFFER:
4065 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4066 bindGenericTransformFeedbackBuffer(buffer);
4067 break;
4068 case GL_UNIFORM_BUFFER:
4069 bindIndexedUniformBuffer(buffer, index, offset, size);
4070 bindGenericUniformBuffer(buffer);
4071 break;
4072 case GL_ATOMIC_COUNTER_BUFFER:
4073 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4074 bindGenericAtomicCounterBuffer(buffer);
4075 break;
4076 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004077 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4078 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004079 break;
4080 default:
4081 UNREACHABLE();
4082 break;
4083 }
4084}
4085
Jamie Madill01a80ee2016-11-07 12:06:18 -05004086void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4087{
4088 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4089 {
4090 bindReadFramebuffer(framebuffer);
4091 }
4092
4093 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4094 {
4095 bindDrawFramebuffer(framebuffer);
4096 }
4097}
4098
4099void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4100{
4101 ASSERT(target == GL_RENDERBUFFER);
4102 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004103 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004104 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004105}
4106
JiangYizhoubddc46b2016-12-09 09:50:51 +08004107void Context::texStorage2DMultisample(GLenum target,
4108 GLsizei samples,
4109 GLenum internalformat,
4110 GLsizei width,
4111 GLsizei height,
4112 GLboolean fixedsamplelocations)
4113{
4114 Extents size(width, height, 1);
4115 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004116 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004117 fixedsamplelocations));
4118}
4119
4120void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4121{
JiangYizhou5b03f472017-01-09 10:22:53 +08004122 // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
4123 // the sample position should be queried by DRAW_FRAMEBUFFER.
4124 mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER);
4125 const Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
JiangYizhoubddc46b2016-12-09 09:50:51 +08004126
4127 switch (pname)
4128 {
4129 case GL_SAMPLE_POSITION:
4130 handleError(framebuffer->getSamplePosition(index, val));
4131 break;
4132 default:
4133 UNREACHABLE();
4134 }
4135}
4136
Jamie Madille8fb6402017-02-14 17:56:40 -05004137void Context::renderbufferStorage(GLenum target,
4138 GLenum internalformat,
4139 GLsizei width,
4140 GLsizei height)
4141{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004142 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4143 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4144
Jamie Madille8fb6402017-02-14 17:56:40 -05004145 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004146 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004147}
4148
4149void Context::renderbufferStorageMultisample(GLenum target,
4150 GLsizei samples,
4151 GLenum internalformat,
4152 GLsizei width,
4153 GLsizei height)
4154{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004155 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4156 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004157
4158 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004159 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004160 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004161}
4162
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004163void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4164{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004165 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004166 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004167}
4168
JiangYizhoue18e6392017-02-20 10:32:23 +08004169void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4170{
4171 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4172 QueryFramebufferParameteriv(framebuffer, pname, params);
4173}
4174
4175void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4176{
4177 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4178 SetFramebufferParameteri(framebuffer, pname, param);
4179}
4180
Jamie Madillb3f26b92017-07-19 15:07:41 -04004181Error Context::getScratchBuffer(size_t requstedSizeBytes,
4182 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004183{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004184 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4185 {
4186 return OutOfMemory() << "Failed to allocate internal buffer.";
4187 }
4188 return NoError();
4189}
4190
4191Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4192 angle::MemoryBuffer **zeroBufferOut) const
4193{
4194 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004195 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004196 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004197 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004198 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004199}
4200
Xinghua Cao2b396592017-03-29 15:36:04 +08004201void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4202{
4203 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4204 {
4205 return;
4206 }
4207
Jamie Madillfe548342017-06-19 11:13:24 -04004208 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004209}
4210
JiangYizhou165361c2017-06-07 14:56:57 +08004211void Context::texStorage2D(GLenum target,
4212 GLsizei levels,
4213 GLenum internalFormat,
4214 GLsizei width,
4215 GLsizei height)
4216{
4217 Extents size(width, height, 1);
4218 Texture *texture = getTargetTexture(target);
4219 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4220}
4221
4222void Context::texStorage3D(GLenum target,
4223 GLsizei levels,
4224 GLenum internalFormat,
4225 GLsizei width,
4226 GLsizei height,
4227 GLsizei depth)
4228{
4229 Extents size(width, height, depth);
4230 Texture *texture = getTargetTexture(target);
4231 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4232}
4233
Jamie Madillc1d770e2017-04-13 17:31:24 -04004234GLenum Context::checkFramebufferStatus(GLenum target)
4235{
4236 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4237 ASSERT(framebuffer);
4238
4239 return framebuffer->checkStatus(this);
4240}
4241
4242void Context::compileShader(GLuint shader)
4243{
4244 Shader *shaderObject = GetValidShader(this, shader);
4245 if (!shaderObject)
4246 {
4247 return;
4248 }
4249 shaderObject->compile(this);
4250}
4251
4252void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4253{
4254 for (int i = 0; i < n; i++)
4255 {
4256 deleteBuffer(buffers[i]);
4257 }
4258}
4259
4260void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4261{
4262 for (int i = 0; i < n; i++)
4263 {
4264 if (framebuffers[i] != 0)
4265 {
4266 deleteFramebuffer(framebuffers[i]);
4267 }
4268 }
4269}
4270
4271void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4272{
4273 for (int i = 0; i < n; i++)
4274 {
4275 deleteRenderbuffer(renderbuffers[i]);
4276 }
4277}
4278
4279void Context::deleteTextures(GLsizei n, const GLuint *textures)
4280{
4281 for (int i = 0; i < n; i++)
4282 {
4283 if (textures[i] != 0)
4284 {
4285 deleteTexture(textures[i]);
4286 }
4287 }
4288}
4289
4290void Context::detachShader(GLuint program, GLuint shader)
4291{
4292 Program *programObject = getProgram(program);
4293 ASSERT(programObject);
4294
4295 Shader *shaderObject = getShader(shader);
4296 ASSERT(shaderObject);
4297
4298 programObject->detachShader(this, shaderObject);
4299}
4300
4301void Context::genBuffers(GLsizei n, GLuint *buffers)
4302{
4303 for (int i = 0; i < n; i++)
4304 {
4305 buffers[i] = createBuffer();
4306 }
4307}
4308
4309void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4310{
4311 for (int i = 0; i < n; i++)
4312 {
4313 framebuffers[i] = createFramebuffer();
4314 }
4315}
4316
4317void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4318{
4319 for (int i = 0; i < n; i++)
4320 {
4321 renderbuffers[i] = createRenderbuffer();
4322 }
4323}
4324
4325void Context::genTextures(GLsizei n, GLuint *textures)
4326{
4327 for (int i = 0; i < n; i++)
4328 {
4329 textures[i] = createTexture();
4330 }
4331}
4332
4333void Context::getActiveAttrib(GLuint program,
4334 GLuint index,
4335 GLsizei bufsize,
4336 GLsizei *length,
4337 GLint *size,
4338 GLenum *type,
4339 GLchar *name)
4340{
4341 Program *programObject = getProgram(program);
4342 ASSERT(programObject);
4343 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4344}
4345
4346void Context::getActiveUniform(GLuint program,
4347 GLuint index,
4348 GLsizei bufsize,
4349 GLsizei *length,
4350 GLint *size,
4351 GLenum *type,
4352 GLchar *name)
4353{
4354 Program *programObject = getProgram(program);
4355 ASSERT(programObject);
4356 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4357}
4358
4359void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4360{
4361 Program *programObject = getProgram(program);
4362 ASSERT(programObject);
4363 programObject->getAttachedShaders(maxcount, count, shaders);
4364}
4365
4366GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4367{
4368 Program *programObject = getProgram(program);
4369 ASSERT(programObject);
4370 return programObject->getAttributeLocation(name);
4371}
4372
4373void Context::getBooleanv(GLenum pname, GLboolean *params)
4374{
4375 GLenum nativeType;
4376 unsigned int numParams = 0;
4377 getQueryParameterInfo(pname, &nativeType, &numParams);
4378
4379 if (nativeType == GL_BOOL)
4380 {
4381 getBooleanvImpl(pname, params);
4382 }
4383 else
4384 {
4385 CastStateValues(this, nativeType, pname, numParams, params);
4386 }
4387}
4388
4389void Context::getFloatv(GLenum pname, GLfloat *params)
4390{
4391 GLenum nativeType;
4392 unsigned int numParams = 0;
4393 getQueryParameterInfo(pname, &nativeType, &numParams);
4394
4395 if (nativeType == GL_FLOAT)
4396 {
4397 getFloatvImpl(pname, params);
4398 }
4399 else
4400 {
4401 CastStateValues(this, nativeType, pname, numParams, params);
4402 }
4403}
4404
4405void Context::getIntegerv(GLenum pname, GLint *params)
4406{
4407 GLenum nativeType;
4408 unsigned int numParams = 0;
4409 getQueryParameterInfo(pname, &nativeType, &numParams);
4410
4411 if (nativeType == GL_INT)
4412 {
4413 getIntegervImpl(pname, params);
4414 }
4415 else
4416 {
4417 CastStateValues(this, nativeType, pname, numParams, params);
4418 }
4419}
4420
4421void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4422{
4423 Program *programObject = getProgram(program);
4424 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004425 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004426}
4427
Jamie Madillbe849e42017-05-02 15:49:00 -04004428void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004429{
4430 Program *programObject = getProgram(program);
4431 ASSERT(programObject);
4432 programObject->getInfoLog(bufsize, length, infolog);
4433}
4434
4435void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4436{
4437 Shader *shaderObject = getShader(shader);
4438 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004439 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004440}
4441
4442void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4443{
4444 Shader *shaderObject = getShader(shader);
4445 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004446 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004447}
4448
4449void Context::getShaderPrecisionFormat(GLenum shadertype,
4450 GLenum precisiontype,
4451 GLint *range,
4452 GLint *precision)
4453{
4454 // TODO(jmadill): Compute shaders.
4455
4456 switch (shadertype)
4457 {
4458 case GL_VERTEX_SHADER:
4459 switch (precisiontype)
4460 {
4461 case GL_LOW_FLOAT:
4462 mCaps.vertexLowpFloat.get(range, precision);
4463 break;
4464 case GL_MEDIUM_FLOAT:
4465 mCaps.vertexMediumpFloat.get(range, precision);
4466 break;
4467 case GL_HIGH_FLOAT:
4468 mCaps.vertexHighpFloat.get(range, precision);
4469 break;
4470
4471 case GL_LOW_INT:
4472 mCaps.vertexLowpInt.get(range, precision);
4473 break;
4474 case GL_MEDIUM_INT:
4475 mCaps.vertexMediumpInt.get(range, precision);
4476 break;
4477 case GL_HIGH_INT:
4478 mCaps.vertexHighpInt.get(range, precision);
4479 break;
4480
4481 default:
4482 UNREACHABLE();
4483 return;
4484 }
4485 break;
4486
4487 case GL_FRAGMENT_SHADER:
4488 switch (precisiontype)
4489 {
4490 case GL_LOW_FLOAT:
4491 mCaps.fragmentLowpFloat.get(range, precision);
4492 break;
4493 case GL_MEDIUM_FLOAT:
4494 mCaps.fragmentMediumpFloat.get(range, precision);
4495 break;
4496 case GL_HIGH_FLOAT:
4497 mCaps.fragmentHighpFloat.get(range, precision);
4498 break;
4499
4500 case GL_LOW_INT:
4501 mCaps.fragmentLowpInt.get(range, precision);
4502 break;
4503 case GL_MEDIUM_INT:
4504 mCaps.fragmentMediumpInt.get(range, precision);
4505 break;
4506 case GL_HIGH_INT:
4507 mCaps.fragmentHighpInt.get(range, precision);
4508 break;
4509
4510 default:
4511 UNREACHABLE();
4512 return;
4513 }
4514 break;
4515
4516 default:
4517 UNREACHABLE();
4518 return;
4519 }
4520}
4521
4522void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4523{
4524 Shader *shaderObject = getShader(shader);
4525 ASSERT(shaderObject);
4526 shaderObject->getSource(bufsize, length, source);
4527}
4528
4529void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4530{
4531 Program *programObject = getProgram(program);
4532 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004533 programObject->getUniformfv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004534}
4535
4536void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4537{
4538 Program *programObject = getProgram(program);
4539 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004540 programObject->getUniformiv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004541}
4542
4543GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4544{
4545 Program *programObject = getProgram(program);
4546 ASSERT(programObject);
4547 return programObject->getUniformLocation(name);
4548}
4549
4550GLboolean Context::isBuffer(GLuint buffer)
4551{
4552 if (buffer == 0)
4553 {
4554 return GL_FALSE;
4555 }
4556
4557 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4558}
4559
4560GLboolean Context::isEnabled(GLenum cap)
4561{
4562 return mGLState.getEnableFeature(cap);
4563}
4564
4565GLboolean Context::isFramebuffer(GLuint framebuffer)
4566{
4567 if (framebuffer == 0)
4568 {
4569 return GL_FALSE;
4570 }
4571
4572 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4573}
4574
4575GLboolean Context::isProgram(GLuint program)
4576{
4577 if (program == 0)
4578 {
4579 return GL_FALSE;
4580 }
4581
4582 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4583}
4584
4585GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4586{
4587 if (renderbuffer == 0)
4588 {
4589 return GL_FALSE;
4590 }
4591
4592 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4593}
4594
4595GLboolean Context::isShader(GLuint shader)
4596{
4597 if (shader == 0)
4598 {
4599 return GL_FALSE;
4600 }
4601
4602 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4603}
4604
4605GLboolean Context::isTexture(GLuint texture)
4606{
4607 if (texture == 0)
4608 {
4609 return GL_FALSE;
4610 }
4611
4612 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4613}
4614
4615void Context::linkProgram(GLuint program)
4616{
4617 Program *programObject = getProgram(program);
4618 ASSERT(programObject);
4619 handleError(programObject->link(this));
Martin Radev0abb7a22017-08-28 15:34:45 +03004620 mGLState.onProgramExecutableChange(programObject);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004621}
4622
4623void Context::releaseShaderCompiler()
4624{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004625 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004626}
4627
4628void Context::shaderBinary(GLsizei n,
4629 const GLuint *shaders,
4630 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004631 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004632 GLsizei length)
4633{
4634 // No binary shader formats are supported.
4635 UNIMPLEMENTED();
4636}
4637
4638void Context::shaderSource(GLuint shader,
4639 GLsizei count,
4640 const GLchar *const *string,
4641 const GLint *length)
4642{
4643 Shader *shaderObject = getShader(shader);
4644 ASSERT(shaderObject);
4645 shaderObject->setSource(count, string, length);
4646}
4647
4648void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4649{
4650 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4651}
4652
4653void Context::stencilMask(GLuint mask)
4654{
4655 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4656}
4657
4658void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4659{
4660 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4661}
4662
4663void Context::uniform1f(GLint location, GLfloat x)
4664{
4665 Program *program = mGLState.getProgram();
4666 program->setUniform1fv(location, 1, &x);
4667}
4668
4669void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4670{
4671 Program *program = mGLState.getProgram();
4672 program->setUniform1fv(location, count, v);
4673}
4674
4675void Context::uniform1i(GLint location, GLint x)
4676{
4677 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004678 if (program->setUniform1iv(location, 1, &x) == Program::SetUniformResult::SamplerChanged)
4679 {
4680 mGLState.setObjectDirty(GL_PROGRAM);
4681 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004682}
4683
4684void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4685{
4686 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004687 if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged)
4688 {
4689 mGLState.setObjectDirty(GL_PROGRAM);
4690 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004691}
4692
4693void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4694{
4695 GLfloat xy[2] = {x, y};
4696 Program *program = mGLState.getProgram();
4697 program->setUniform2fv(location, 1, xy);
4698}
4699
4700void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4701{
4702 Program *program = mGLState.getProgram();
4703 program->setUniform2fv(location, count, v);
4704}
4705
4706void Context::uniform2i(GLint location, GLint x, GLint y)
4707{
4708 GLint xy[2] = {x, y};
4709 Program *program = mGLState.getProgram();
4710 program->setUniform2iv(location, 1, xy);
4711}
4712
4713void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4714{
4715 Program *program = mGLState.getProgram();
4716 program->setUniform2iv(location, count, v);
4717}
4718
4719void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4720{
4721 GLfloat xyz[3] = {x, y, z};
4722 Program *program = mGLState.getProgram();
4723 program->setUniform3fv(location, 1, xyz);
4724}
4725
4726void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4727{
4728 Program *program = mGLState.getProgram();
4729 program->setUniform3fv(location, count, v);
4730}
4731
4732void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4733{
4734 GLint xyz[3] = {x, y, z};
4735 Program *program = mGLState.getProgram();
4736 program->setUniform3iv(location, 1, xyz);
4737}
4738
4739void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4740{
4741 Program *program = mGLState.getProgram();
4742 program->setUniform3iv(location, count, v);
4743}
4744
4745void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4746{
4747 GLfloat xyzw[4] = {x, y, z, w};
4748 Program *program = mGLState.getProgram();
4749 program->setUniform4fv(location, 1, xyzw);
4750}
4751
4752void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4753{
4754 Program *program = mGLState.getProgram();
4755 program->setUniform4fv(location, count, v);
4756}
4757
4758void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4759{
4760 GLint xyzw[4] = {x, y, z, w};
4761 Program *program = mGLState.getProgram();
4762 program->setUniform4iv(location, 1, xyzw);
4763}
4764
4765void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4766{
4767 Program *program = mGLState.getProgram();
4768 program->setUniform4iv(location, count, v);
4769}
4770
4771void Context::uniformMatrix2fv(GLint location,
4772 GLsizei count,
4773 GLboolean transpose,
4774 const GLfloat *value)
4775{
4776 Program *program = mGLState.getProgram();
4777 program->setUniformMatrix2fv(location, count, transpose, value);
4778}
4779
4780void Context::uniformMatrix3fv(GLint location,
4781 GLsizei count,
4782 GLboolean transpose,
4783 const GLfloat *value)
4784{
4785 Program *program = mGLState.getProgram();
4786 program->setUniformMatrix3fv(location, count, transpose, value);
4787}
4788
4789void Context::uniformMatrix4fv(GLint location,
4790 GLsizei count,
4791 GLboolean transpose,
4792 const GLfloat *value)
4793{
4794 Program *program = mGLState.getProgram();
4795 program->setUniformMatrix4fv(location, count, transpose, value);
4796}
4797
4798void Context::validateProgram(GLuint program)
4799{
4800 Program *programObject = getProgram(program);
4801 ASSERT(programObject);
4802 programObject->validate(mCaps);
4803}
4804
Jamie Madilld04908b2017-06-09 14:15:35 -04004805void Context::getProgramBinary(GLuint program,
4806 GLsizei bufSize,
4807 GLsizei *length,
4808 GLenum *binaryFormat,
4809 void *binary)
4810{
4811 Program *programObject = getProgram(program);
4812 ASSERT(programObject != nullptr);
4813
4814 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4815}
4816
4817void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4818{
4819 Program *programObject = getProgram(program);
4820 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004821
Jamie Madilld04908b2017-06-09 14:15:35 -04004822 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4823}
4824
Jamie Madillff325f12017-08-26 15:06:05 -04004825void Context::uniform1ui(GLint location, GLuint v0)
4826{
4827 Program *program = mGLState.getProgram();
4828 program->setUniform1uiv(location, 1, &v0);
4829}
4830
4831void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4832{
4833 Program *program = mGLState.getProgram();
4834 const GLuint xy[] = {v0, v1};
4835 program->setUniform2uiv(location, 1, xy);
4836}
4837
4838void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4839{
4840 Program *program = mGLState.getProgram();
4841 const GLuint xyz[] = {v0, v1, v2};
4842 program->setUniform3uiv(location, 1, xyz);
4843}
4844
4845void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4846{
4847 Program *program = mGLState.getProgram();
4848 const GLuint xyzw[] = {v0, v1, v2, v3};
4849 program->setUniform4uiv(location, 1, xyzw);
4850}
4851
4852void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4853{
4854 Program *program = mGLState.getProgram();
4855 program->setUniform1uiv(location, count, value);
4856}
4857void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4858{
4859 Program *program = mGLState.getProgram();
4860 program->setUniform2uiv(location, count, value);
4861}
4862
4863void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4864{
4865 Program *program = mGLState.getProgram();
4866 program->setUniform3uiv(location, count, value);
4867}
4868
4869void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4870{
4871 Program *program = mGLState.getProgram();
4872 program->setUniform4uiv(location, count, value);
4873}
4874
Jamie Madillf0e04492017-08-26 15:28:42 -04004875void Context::genQueries(GLsizei n, GLuint *ids)
4876{
4877 for (GLsizei i = 0; i < n; i++)
4878 {
4879 GLuint handle = mQueryHandleAllocator.allocate();
4880 mQueryMap.assign(handle, nullptr);
4881 ids[i] = handle;
4882 }
4883}
4884
4885void Context::deleteQueries(GLsizei n, const GLuint *ids)
4886{
4887 for (int i = 0; i < n; i++)
4888 {
4889 GLuint query = ids[i];
4890
4891 Query *queryObject = nullptr;
4892 if (mQueryMap.erase(query, &queryObject))
4893 {
4894 mQueryHandleAllocator.release(query);
4895 if (queryObject)
4896 {
4897 queryObject->release(this);
4898 }
4899 }
4900 }
4901}
4902
4903GLboolean Context::isQuery(GLuint id)
4904{
4905 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4906}
4907
Jamie Madillc8c95812017-08-26 18:40:09 -04004908void Context::uniformMatrix2x3fv(GLint location,
4909 GLsizei count,
4910 GLboolean transpose,
4911 const GLfloat *value)
4912{
4913 Program *program = mGLState.getProgram();
4914 program->setUniformMatrix2x3fv(location, count, transpose, value);
4915}
4916
4917void Context::uniformMatrix3x2fv(GLint location,
4918 GLsizei count,
4919 GLboolean transpose,
4920 const GLfloat *value)
4921{
4922 Program *program = mGLState.getProgram();
4923 program->setUniformMatrix3x2fv(location, count, transpose, value);
4924}
4925
4926void Context::uniformMatrix2x4fv(GLint location,
4927 GLsizei count,
4928 GLboolean transpose,
4929 const GLfloat *value)
4930{
4931 Program *program = mGLState.getProgram();
4932 program->setUniformMatrix2x4fv(location, count, transpose, value);
4933}
4934
4935void Context::uniformMatrix4x2fv(GLint location,
4936 GLsizei count,
4937 GLboolean transpose,
4938 const GLfloat *value)
4939{
4940 Program *program = mGLState.getProgram();
4941 program->setUniformMatrix4x2fv(location, count, transpose, value);
4942}
4943
4944void Context::uniformMatrix3x4fv(GLint location,
4945 GLsizei count,
4946 GLboolean transpose,
4947 const GLfloat *value)
4948{
4949 Program *program = mGLState.getProgram();
4950 program->setUniformMatrix3x4fv(location, count, transpose, value);
4951}
4952
4953void Context::uniformMatrix4x3fv(GLint location,
4954 GLsizei count,
4955 GLboolean transpose,
4956 const GLfloat *value)
4957{
4958 Program *program = mGLState.getProgram();
4959 program->setUniformMatrix4x3fv(location, count, transpose, value);
4960}
4961
Jamie Madilld7576732017-08-26 18:49:50 -04004962void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
4963{
4964 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4965 {
4966 GLuint vertexArray = arrays[arrayIndex];
4967
4968 if (arrays[arrayIndex] != 0)
4969 {
4970 VertexArray *vertexArrayObject = nullptr;
4971 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
4972 {
4973 if (vertexArrayObject != nullptr)
4974 {
4975 detachVertexArray(vertexArray);
4976 vertexArrayObject->onDestroy(this);
4977 }
4978
4979 mVertexArrayHandleAllocator.release(vertexArray);
4980 }
4981 }
4982 }
4983}
4984
4985void Context::genVertexArrays(GLsizei n, GLuint *arrays)
4986{
4987 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4988 {
4989 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
4990 mVertexArrayMap.assign(vertexArray, nullptr);
4991 arrays[arrayIndex] = vertexArray;
4992 }
4993}
4994
4995bool Context::isVertexArray(GLuint array)
4996{
4997 if (array == 0)
4998 {
4999 return GL_FALSE;
5000 }
5001
5002 VertexArray *vao = getVertexArray(array);
5003 return (vao != nullptr ? GL_TRUE : GL_FALSE);
5004}
5005
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04005006void Context::endTransformFeedback()
5007{
5008 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5009 transformFeedback->end(this);
5010}
5011
5012void Context::transformFeedbackVaryings(GLuint program,
5013 GLsizei count,
5014 const GLchar *const *varyings,
5015 GLenum bufferMode)
5016{
5017 Program *programObject = getProgram(program);
5018 ASSERT(programObject);
5019 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
5020}
5021
5022void Context::getTransformFeedbackVarying(GLuint program,
5023 GLuint index,
5024 GLsizei bufSize,
5025 GLsizei *length,
5026 GLsizei *size,
5027 GLenum *type,
5028 GLchar *name)
5029{
5030 Program *programObject = getProgram(program);
5031 ASSERT(programObject);
5032 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5033}
5034
5035void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5036{
5037 for (int i = 0; i < n; i++)
5038 {
5039 GLuint transformFeedback = ids[i];
5040 if (transformFeedback == 0)
5041 {
5042 continue;
5043 }
5044
5045 TransformFeedback *transformFeedbackObject = nullptr;
5046 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5047 {
5048 if (transformFeedbackObject != nullptr)
5049 {
5050 detachTransformFeedback(transformFeedback);
5051 transformFeedbackObject->release(this);
5052 }
5053
5054 mTransformFeedbackHandleAllocator.release(transformFeedback);
5055 }
5056 }
5057}
5058
5059void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5060{
5061 for (int i = 0; i < n; i++)
5062 {
5063 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5064 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5065 ids[i] = transformFeedback;
5066 }
5067}
5068
5069bool Context::isTransformFeedback(GLuint id)
5070{
5071 if (id == 0)
5072 {
5073 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5074 // returns FALSE
5075 return GL_FALSE;
5076 }
5077
5078 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5079 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5080}
5081
5082void Context::pauseTransformFeedback()
5083{
5084 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5085 transformFeedback->pause();
5086}
5087
5088void Context::resumeTransformFeedback()
5089{
5090 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5091 transformFeedback->resume();
5092}
5093
Jamie Madill12e957f2017-08-26 21:42:26 -04005094void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5095{
5096 const Program *programObject = getProgram(program);
Jamie Madill54164b02017-08-28 15:17:37 -04005097 programObject->getUniformuiv(this, location, params);
Jamie Madill12e957f2017-08-26 21:42:26 -04005098}
5099
5100GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5101{
5102 const Program *programObject = getProgram(program);
5103 return programObject->getFragDataLocation(name);
5104}
5105
5106void Context::getUniformIndices(GLuint program,
5107 GLsizei uniformCount,
5108 const GLchar *const *uniformNames,
5109 GLuint *uniformIndices)
5110{
5111 const Program *programObject = getProgram(program);
5112 if (!programObject->isLinked())
5113 {
5114 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5115 {
5116 uniformIndices[uniformId] = GL_INVALID_INDEX;
5117 }
5118 }
5119 else
5120 {
5121 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5122 {
5123 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5124 }
5125 }
5126}
5127
5128void Context::getActiveUniformsiv(GLuint program,
5129 GLsizei uniformCount,
5130 const GLuint *uniformIndices,
5131 GLenum pname,
5132 GLint *params)
5133{
5134 const Program *programObject = getProgram(program);
5135 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5136 {
5137 const GLuint index = uniformIndices[uniformId];
5138 params[uniformId] = programObject->getActiveUniformi(index, pname);
5139 }
5140}
5141
5142GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5143{
5144 const Program *programObject = getProgram(program);
5145 return programObject->getUniformBlockIndex(uniformBlockName);
5146}
5147
5148void Context::getActiveUniformBlockiv(GLuint program,
5149 GLuint uniformBlockIndex,
5150 GLenum pname,
5151 GLint *params)
5152{
5153 const Program *programObject = getProgram(program);
5154 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5155}
5156
5157void Context::getActiveUniformBlockName(GLuint program,
5158 GLuint uniformBlockIndex,
5159 GLsizei bufSize,
5160 GLsizei *length,
5161 GLchar *uniformBlockName)
5162{
5163 const Program *programObject = getProgram(program);
5164 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5165}
5166
5167void Context::uniformBlockBinding(GLuint program,
5168 GLuint uniformBlockIndex,
5169 GLuint uniformBlockBinding)
5170{
5171 Program *programObject = getProgram(program);
5172 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5173}
5174
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005175GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5176{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005177 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5178 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005179
Jamie Madill70b5bb02017-08-28 13:32:37 -04005180 Sync *syncObject = getSync(syncHandle);
5181 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005182 if (error.isError())
5183 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005184 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005185 handleError(error);
5186 return nullptr;
5187 }
5188
Jamie Madill70b5bb02017-08-28 13:32:37 -04005189 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005190}
5191
5192GLboolean Context::isSync(GLsync sync)
5193{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005194 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005195}
5196
5197GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5198{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005199 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005200
5201 GLenum result = GL_WAIT_FAILED;
5202 handleError(syncObject->clientWait(flags, timeout, &result));
5203 return result;
5204}
5205
5206void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5207{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005208 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005209 handleError(syncObject->serverWait(flags, timeout));
5210}
5211
5212void Context::getInteger64v(GLenum pname, GLint64 *params)
5213{
5214 GLenum nativeType = GL_NONE;
5215 unsigned int numParams = 0;
5216 getQueryParameterInfo(pname, &nativeType, &numParams);
5217
5218 if (nativeType == GL_INT_64_ANGLEX)
5219 {
5220 getInteger64vImpl(pname, params);
5221 }
5222 else
5223 {
5224 CastStateValues(this, nativeType, pname, numParams, params);
5225 }
5226}
5227
Jamie Madill3ef140a2017-08-26 23:11:21 -04005228void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5229{
5230 Buffer *buffer = mGLState.getTargetBuffer(target);
5231 QueryBufferParameteri64v(buffer, pname, params);
5232}
5233
5234void Context::genSamplers(GLsizei count, GLuint *samplers)
5235{
5236 for (int i = 0; i < count; i++)
5237 {
5238 samplers[i] = mState.mSamplers->createSampler();
5239 }
5240}
5241
5242void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5243{
5244 for (int i = 0; i < count; i++)
5245 {
5246 GLuint sampler = samplers[i];
5247
5248 if (mState.mSamplers->getSampler(sampler))
5249 {
5250 detachSampler(sampler);
5251 }
5252
5253 mState.mSamplers->deleteObject(this, sampler);
5254 }
5255}
5256
5257void Context::getInternalformativ(GLenum target,
5258 GLenum internalformat,
5259 GLenum pname,
5260 GLsizei bufSize,
5261 GLint *params)
5262{
5263 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5264 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5265}
5266
Jamie Madill81c2e252017-09-09 23:32:46 -04005267void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
5268{
5269 Program *programObject = getProgram(program);
5270 ASSERT(programObject);
5271 if (programObject->setUniform1iv(location, count, value) ==
5272 Program::SetUniformResult::SamplerChanged)
5273 {
5274 mGLState.setObjectDirty(GL_PROGRAM);
5275 }
5276}
5277
5278void Context::onTextureChange(const Texture *texture)
5279{
5280 // Conservatively assume all textures are dirty.
5281 // TODO(jmadill): More fine-grained update.
5282 mGLState.setObjectDirty(GL_TEXTURE);
5283}
5284
Jamie Madillc29968b2016-01-20 11:17:23 -05005285} // namespace gl