blob: 53b6d32f381047519e248592ff31208dbfd7b8de [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 Madill4e0e6f82017-02-17 11:06:03 -0500283 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700284 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400285
Jamie Madill4928b7c2017-06-20 12:57:39 -0400286 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400287 GetClientArraysEnabled(attribs), robustResourceInit,
288 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100289
Shannon Woods53a94a82014-06-24 15:20:36 -0400290 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400291
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000292 // [OpenGL ES 2.0.24] section 3.7 page 83:
293 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
294 // and cube map texture state vectors respectively associated with them.
295 // In order that access to these initial textures not be lost, they are treated as texture
296 // objects all of whose names are 0.
297
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400298 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400299 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500300
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400301 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400302 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400303
Geoff Langeb66a6e2016-10-31 13:06:12 -0400304 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400305 {
306 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400307 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400308 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400309
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400310 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400311 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312 }
Geoff Lang3b573612016-10-31 14:08:10 -0400313 if (getClientVersion() >= Version(3, 1))
314 {
315 Texture *zeroTexture2DMultisample =
316 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400317 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800318
319 bindGenericAtomicCounterBuffer(0);
320 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
321 {
322 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
323 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800324
325 bindGenericShaderStorageBuffer(0);
326 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
327 {
328 bindIndexedShaderStorageBuffer(0, i, 0, 0);
329 }
Geoff Lang3b573612016-10-31 14:08:10 -0400330 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000331
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400332 if (mExtensions.textureRectangle)
333 {
334 Texture *zeroTextureRectangle =
335 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
336 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
337 }
338
Ian Ewellbda75592016-04-18 17:25:54 -0400339 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
340 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400341 Texture *zeroTextureExternal =
342 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400343 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400344 }
345
Jamie Madill4928b7c2017-06-20 12:57:39 -0400346 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500347
Jamie Madill57a89722013-07-02 11:57:03 -0400348 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000349 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800350 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000351 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400352
Jamie Madill01a80ee2016-11-07 12:06:18 -0500353 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000354
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000355 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500356 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000357 {
358 bindIndexedUniformBuffer(0, i, 0, -1);
359 }
360
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000361 bindCopyReadBuffer(0);
362 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000363 bindPixelPackBuffer(0);
364 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000365
Geoff Langeb66a6e2016-10-31 13:06:12 -0400366 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400367 {
368 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
369 // In the initial state, a default transform feedback object is bound and treated as
370 // a transform feedback object with a name of zero. That object is bound any time
371 // BindTransformFeedback is called with id of zero
Jamie Madillf0dcb8b2017-08-26 19:05:13 -0400372 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Geoff Lang1a683462015-09-29 15:09:59 -0400373 }
Geoff Langc8058452014-02-03 12:04:11 -0500374
Jamie Madillad9f24e2016-02-12 09:27:24 -0500375 // Initialize dirty bit masks
376 // TODO(jmadill): additional ES3 state
377 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
378 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
379 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
380 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
381 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
382 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400383 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500384 // No dirty objects.
385
386 // Readpixels uses the pack state and read FBO
387 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
388 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
389 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
390 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
391 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400392 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500393 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
394
395 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
396 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
397 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
398 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
399 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
400 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
401 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
402 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
403 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
404 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
405 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
406 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
407
408 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
409 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700410 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500411 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
412 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400413
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400414 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000415}
416
Jamie Madill4928b7c2017-06-20 12:57:39 -0400417egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418{
Corentin Wallez80b24112015-08-25 16:41:57 -0400419 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400421 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400423 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000424
Corentin Wallez80b24112015-08-25 16:41:57 -0400425 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400427 if (query.second != nullptr)
428 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400429 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400430 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400432 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000433
Corentin Wallez80b24112015-08-25 16:41:57 -0400434 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400435 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400436 if (vertexArray.second)
437 {
438 vertexArray.second->onDestroy(this);
439 }
Jamie Madill57a89722013-07-02 11:57:03 -0400440 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400441 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400442
Corentin Wallez80b24112015-08-25 16:41:57 -0400443 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500444 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500445 if (transformFeedback.second != nullptr)
446 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500447 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500448 }
Geoff Langc8058452014-02-03 12:04:11 -0500449 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400450 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500451
Jamie Madilldedd7b92014-11-05 16:30:36 -0500452 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400453 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400454 zeroTexture.second->onDestroy(this);
455 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400456 }
457 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000458
Corentin Wallezccab69d2017-01-27 16:57:15 -0500459 SafeDelete(mSurfacelessFramebuffer);
460
Jamie Madill4928b7c2017-06-20 12:57:39 -0400461 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400462 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500463
Jamie Madill4928b7c2017-06-20 12:57:39 -0400464 mGLState.reset(this);
465
Jamie Madill6c1f6712017-02-14 19:08:04 -0500466 mState.mBuffers->release(this);
467 mState.mShaderPrograms->release(this);
468 mState.mTextures->release(this);
469 mState.mRenderbuffers->release(this);
470 mState.mSamplers->release(this);
Jamie Madill70b5bb02017-08-28 13:32:37 -0400471 mState.mSyncs->release(this);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500472 mState.mPaths->release(this);
473 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400474
475 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000476}
477
Jamie Madill70ee0f62017-02-06 16:04:20 -0500478Context::~Context()
479{
480}
481
Jamie Madill4928b7c2017-06-20 12:57:39 -0400482egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000483{
Jamie Madill61e16b42017-06-19 11:13:23 -0400484 mCurrentDisplay = display;
485
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000486 if (!mHasBeenCurrent)
487 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500489 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400490 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000491
Corentin Wallezc295e512017-01-27 17:47:50 -0500492 int width = 0;
493 int height = 0;
494 if (surface != nullptr)
495 {
496 width = surface->getWidth();
497 height = surface->getHeight();
498 }
499
500 mGLState.setViewportParams(0, 0, width, height);
501 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000502
503 mHasBeenCurrent = true;
504 }
505
Jamie Madill1b94d432015-08-07 13:23:23 -0400506 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700507 mGLState.setAllDirtyBits();
Jamie Madill81c2e252017-09-09 23:32:46 -0400508 mGLState.setAllDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -0400509
Jamie Madill4928b7c2017-06-20 12:57:39 -0400510 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500511
512 Framebuffer *newDefault = nullptr;
513 if (surface != nullptr)
514 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400515 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500516 mCurrentSurface = surface;
517 newDefault = surface->getDefaultFramebuffer();
518 }
519 else
520 {
521 if (mSurfacelessFramebuffer == nullptr)
522 {
523 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
524 }
525
526 newDefault = mSurfacelessFramebuffer;
527 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000528
Corentin Wallez37c39792015-08-20 14:19:46 -0400529 // Update default framebuffer, the binding of the previous default
530 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400531 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700532 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400533 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700534 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400535 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700536 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400537 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700538 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400539 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500540 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400541 }
Ian Ewell292f0052016-02-04 10:37:32 -0500542
543 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400544 mImplementation->onMakeCurrent(this);
545 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000546}
547
Jamie Madill4928b7c2017-06-20 12:57:39 -0400548egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400549{
Corentin Wallez37c39792015-08-20 14:19:46 -0400550 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500551 Framebuffer *currentDefault = nullptr;
552 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400553 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500554 currentDefault = mCurrentSurface->getDefaultFramebuffer();
555 }
556 else if (mSurfacelessFramebuffer != nullptr)
557 {
558 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400559 }
560
Corentin Wallezc295e512017-01-27 17:47:50 -0500561 if (mGLState.getReadFramebuffer() == currentDefault)
562 {
563 mGLState.setReadFramebufferBinding(nullptr);
564 }
565 if (mGLState.getDrawFramebuffer() == currentDefault)
566 {
567 mGLState.setDrawFramebufferBinding(nullptr);
568 }
569 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
570
571 if (mCurrentSurface)
572 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400573 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500574 mCurrentSurface = nullptr;
575 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400576
577 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400578}
579
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580GLuint Context::createBuffer()
581{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500582 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000583}
584
585GLuint Context::createProgram()
586{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500587 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000588}
589
590GLuint Context::createShader(GLenum type)
591{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500592 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000593}
594
595GLuint Context::createTexture()
596{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500597 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000598}
599
600GLuint Context::createRenderbuffer()
601{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500602 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603}
604
Sami Väisänene45e53b2016-05-25 10:36:04 +0300605GLuint Context::createPaths(GLsizei range)
606{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500607 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300608 if (resultOrError.isError())
609 {
610 handleError(resultOrError.getError());
611 return 0;
612 }
613 return resultOrError.getResult();
614}
615
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000616// Returns an unused framebuffer name
617GLuint Context::createFramebuffer()
618{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500619 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620}
621
Jamie Madill33dc8432013-07-26 11:55:05 -0400622GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000623{
Jamie Madill33dc8432013-07-26 11:55:05 -0400624 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400625 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626 return handle;
627}
628
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629void Context::deleteBuffer(GLuint buffer)
630{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500631 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000632 {
633 detachBuffer(buffer);
634 }
Jamie Madill893ab082014-05-16 16:56:10 -0400635
Jamie Madill6c1f6712017-02-14 19:08:04 -0500636 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637}
638
639void Context::deleteShader(GLuint shader)
640{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500641 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000642}
643
644void Context::deleteProgram(GLuint program)
645{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500646 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000647}
648
649void Context::deleteTexture(GLuint texture)
650{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500651 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000652 {
653 detachTexture(texture);
654 }
655
Jamie Madill6c1f6712017-02-14 19:08:04 -0500656 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000657}
658
659void Context::deleteRenderbuffer(GLuint renderbuffer)
660{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500661 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000662 {
663 detachRenderbuffer(renderbuffer);
664 }
Jamie Madill893ab082014-05-16 16:56:10 -0400665
Jamie Madill6c1f6712017-02-14 19:08:04 -0500666 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000667}
668
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400669void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400670{
671 // The spec specifies the underlying Fence object is not deleted until all current
672 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
673 // and since our API is currently designed for being called from a single thread, we can delete
674 // the fence immediately.
Jamie Madill70b5bb02017-08-28 13:32:37 -0400675 mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400676}
677
Sami Väisänene45e53b2016-05-25 10:36:04 +0300678void Context::deletePaths(GLuint first, GLsizei range)
679{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500680 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300681}
682
683bool Context::hasPathData(GLuint path) const
684{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500685 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300686 if (pathObj == nullptr)
687 return false;
688
689 return pathObj->hasPathData();
690}
691
692bool Context::hasPath(GLuint path) const
693{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500694 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300695}
696
697void Context::setPathCommands(GLuint path,
698 GLsizei numCommands,
699 const GLubyte *commands,
700 GLsizei numCoords,
701 GLenum coordType,
702 const void *coords)
703{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500704 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300705
706 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
707}
708
709void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
710{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500711 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300712
713 switch (pname)
714 {
715 case GL_PATH_STROKE_WIDTH_CHROMIUM:
716 pathObj->setStrokeWidth(value);
717 break;
718 case GL_PATH_END_CAPS_CHROMIUM:
719 pathObj->setEndCaps(static_cast<GLenum>(value));
720 break;
721 case GL_PATH_JOIN_STYLE_CHROMIUM:
722 pathObj->setJoinStyle(static_cast<GLenum>(value));
723 break;
724 case GL_PATH_MITER_LIMIT_CHROMIUM:
725 pathObj->setMiterLimit(value);
726 break;
727 case GL_PATH_STROKE_BOUND_CHROMIUM:
728 pathObj->setStrokeBound(value);
729 break;
730 default:
731 UNREACHABLE();
732 break;
733 }
734}
735
736void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
737{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500738 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300739
740 switch (pname)
741 {
742 case GL_PATH_STROKE_WIDTH_CHROMIUM:
743 *value = pathObj->getStrokeWidth();
744 break;
745 case GL_PATH_END_CAPS_CHROMIUM:
746 *value = static_cast<GLfloat>(pathObj->getEndCaps());
747 break;
748 case GL_PATH_JOIN_STYLE_CHROMIUM:
749 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
750 break;
751 case GL_PATH_MITER_LIMIT_CHROMIUM:
752 *value = pathObj->getMiterLimit();
753 break;
754 case GL_PATH_STROKE_BOUND_CHROMIUM:
755 *value = pathObj->getStrokeBound();
756 break;
757 default:
758 UNREACHABLE();
759 break;
760 }
761}
762
763void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
764{
765 mGLState.setPathStencilFunc(func, ref, mask);
766}
767
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000768void Context::deleteFramebuffer(GLuint framebuffer)
769{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500770 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000771 {
772 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000773 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500774
Jamie Madill6c1f6712017-02-14 19:08:04 -0500775 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000776}
777
Jamie Madill33dc8432013-07-26 11:55:05 -0400778void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000779{
Jamie Madill96a483b2017-06-27 16:49:21 -0400780 FenceNV *fenceObject = nullptr;
781 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000782 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400783 mFenceNVHandleAllocator.release(fence);
784 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000785 }
786}
787
Geoff Lang70d0f492015-12-10 17:45:46 -0500788Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000789{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500790 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000791}
792
Jamie Madill570f7c82014-07-03 10:38:54 -0400793Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500795 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796}
797
Geoff Lang70d0f492015-12-10 17:45:46 -0500798Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000799{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500800 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801}
802
Jamie Madill70b5bb02017-08-28 13:32:37 -0400803Sync *Context::getSync(GLsync handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400804{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400805 return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400806}
807
Jamie Madill57a89722013-07-02 11:57:03 -0400808VertexArray *Context::getVertexArray(GLuint handle) const
809{
Jamie Madill96a483b2017-06-27 16:49:21 -0400810 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400811}
812
Jamie Madilldc356042013-07-19 16:36:57 -0400813Sampler *Context::getSampler(GLuint handle) const
814{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500815 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400816}
817
Geoff Langc8058452014-02-03 12:04:11 -0500818TransformFeedback *Context::getTransformFeedback(GLuint handle) const
819{
Jamie Madill96a483b2017-06-27 16:49:21 -0400820 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500821}
822
Geoff Lang70d0f492015-12-10 17:45:46 -0500823LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
824{
825 switch (identifier)
826 {
827 case GL_BUFFER:
828 return getBuffer(name);
829 case GL_SHADER:
830 return getShader(name);
831 case GL_PROGRAM:
832 return getProgram(name);
833 case GL_VERTEX_ARRAY:
834 return getVertexArray(name);
835 case GL_QUERY:
836 return getQuery(name);
837 case GL_TRANSFORM_FEEDBACK:
838 return getTransformFeedback(name);
839 case GL_SAMPLER:
840 return getSampler(name);
841 case GL_TEXTURE:
842 return getTexture(name);
843 case GL_RENDERBUFFER:
844 return getRenderbuffer(name);
845 case GL_FRAMEBUFFER:
846 return getFramebuffer(name);
847 default:
848 UNREACHABLE();
849 return nullptr;
850 }
851}
852
853LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
854{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400855 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
Geoff Lang70d0f492015-12-10 17:45:46 -0500856}
857
Martin Radev9d901792016-07-15 15:58:58 +0300858void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
859{
860 LabeledObject *object = getLabeledObject(identifier, name);
861 ASSERT(object != nullptr);
862
863 std::string labelName = GetObjectLabelFromPointer(length, label);
864 object->setLabel(labelName);
Jamie Madill8693bdb2017-09-02 15:32:14 -0400865
866 // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
867 // specified object is active until we do this.
868 mGLState.setObjectDirty(identifier);
Martin Radev9d901792016-07-15 15:58:58 +0300869}
870
871void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
872{
873 LabeledObject *object = getLabeledObjectFromPtr(ptr);
874 ASSERT(object != nullptr);
875
876 std::string labelName = GetObjectLabelFromPointer(length, label);
877 object->setLabel(labelName);
878}
879
880void Context::getObjectLabel(GLenum identifier,
881 GLuint name,
882 GLsizei bufSize,
883 GLsizei *length,
884 GLchar *label) const
885{
886 LabeledObject *object = getLabeledObject(identifier, name);
887 ASSERT(object != nullptr);
888
889 const std::string &objectLabel = object->getLabel();
890 GetObjectLabelBase(objectLabel, bufSize, length, label);
891}
892
893void Context::getObjectPtrLabel(const void *ptr,
894 GLsizei bufSize,
895 GLsizei *length,
896 GLchar *label) const
897{
898 LabeledObject *object = getLabeledObjectFromPtr(ptr);
899 ASSERT(object != nullptr);
900
901 const std::string &objectLabel = object->getLabel();
902 GetObjectLabelBase(objectLabel, bufSize, length, label);
903}
904
Jamie Madilldc356042013-07-19 16:36:57 -0400905bool Context::isSampler(GLuint samplerName) const
906{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500907 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400908}
909
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500910void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000911{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500912 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400913 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000914}
915
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800916void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
917{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500918 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400919 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800920}
921
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500922void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000923{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500924 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400925 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000926}
927
Jamie Madilldedd7b92014-11-05 16:30:36 -0500928void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000929{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500930 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000931
Jamie Madilldedd7b92014-11-05 16:30:36 -0500932 if (handle == 0)
933 {
934 texture = mZeroTextures[target].get();
935 }
936 else
937 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500938 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500939 }
940
941 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400942 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000943}
944
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500945void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000946{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500947 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
948 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700949 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950}
951
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500952void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500954 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
955 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700956 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000957}
958
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500959void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400960{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500961 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700962 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400963}
964
Shao80957d92017-02-20 21:25:59 +0800965void Context::bindVertexBuffer(GLuint bindingIndex,
966 GLuint bufferHandle,
967 GLintptr offset,
968 GLsizei stride)
969{
970 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400971 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +0800972}
973
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500974void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400975{
Geoff Lang76b10c92014-09-05 16:28:14 -0400976 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400977 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500978 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400979 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400980}
981
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800982void Context::bindImageTexture(GLuint unit,
983 GLuint texture,
984 GLint level,
985 GLboolean layered,
986 GLint layer,
987 GLenum access,
988 GLenum format)
989{
990 Texture *tex = mState.mTextures->getTexture(texture);
991 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
992}
993
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500994void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500996 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400997 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000998}
999
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001000void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1001 GLuint index,
1002 GLintptr offset,
1003 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001004{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001005 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001006 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001007}
1008
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001009void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001010{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001011 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001012 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001013}
1014
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001015void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1016 GLuint index,
1017 GLintptr offset,
1018 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001019{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001020 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001021 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001022}
1023
Jiajia Qin6eafb042016-12-27 17:04:07 +08001024void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1025{
1026 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001027 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001028}
1029
1030void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1031 GLuint index,
1032 GLintptr offset,
1033 GLsizeiptr size)
1034{
1035 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001036 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001037}
1038
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001039void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1040{
1041 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001042 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001043}
1044
1045void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1046 GLuint index,
1047 GLintptr offset,
1048 GLsizeiptr size)
1049{
1050 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001051 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001052}
1053
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001054void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001055{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001056 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001057 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001061{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001062 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001063 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001067{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001068 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001069 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001070}
1071
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001072void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001073{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001074 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001075 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001076}
1077
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001078void Context::useProgram(GLuint program)
1079{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001080 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001081}
1082
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001083void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001084{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001085 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001086 TransformFeedback *transformFeedback =
1087 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001088 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001089}
1090
Jamie Madillf0e04492017-08-26 15:28:42 -04001091void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001092{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001093 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001094 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095
Geoff Lang5aad9672014-09-08 11:10:42 -04001096 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001097 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001098
1099 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001100 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001101}
1102
Jamie Madillf0e04492017-08-26 15:28:42 -04001103void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001104{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001105 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001106 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001107
Jamie Madillf0e04492017-08-26 15:28:42 -04001108 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001109
Geoff Lang5aad9672014-09-08 11:10:42 -04001110 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001111 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001112}
1113
Jamie Madillf0e04492017-08-26 15:28:42 -04001114void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001115{
1116 ASSERT(target == GL_TIMESTAMP_EXT);
1117
1118 Query *queryObject = getQuery(id, true, target);
1119 ASSERT(queryObject);
1120
Jamie Madillf0e04492017-08-26 15:28:42 -04001121 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001122}
1123
1124void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1125{
1126 switch (pname)
1127 {
1128 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001129 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001130 break;
1131 case GL_QUERY_COUNTER_BITS_EXT:
1132 switch (target)
1133 {
1134 case GL_TIME_ELAPSED_EXT:
1135 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1136 break;
1137 case GL_TIMESTAMP_EXT:
1138 params[0] = getExtensions().queryCounterBitsTimestamp;
1139 break;
1140 default:
1141 UNREACHABLE();
1142 params[0] = 0;
1143 break;
1144 }
1145 break;
1146 default:
1147 UNREACHABLE();
1148 return;
1149 }
1150}
1151
Geoff Lang2186c382016-10-14 10:54:54 -04001152void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001153{
Geoff Lang2186c382016-10-14 10:54:54 -04001154 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001155}
1156
Geoff Lang2186c382016-10-14 10:54:54 -04001157void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001158{
Geoff Lang2186c382016-10-14 10:54:54 -04001159 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001160}
1161
Geoff Lang2186c382016-10-14 10:54:54 -04001162void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001163{
Geoff Lang2186c382016-10-14 10:54:54 -04001164 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001165}
1166
Geoff Lang2186c382016-10-14 10:54:54 -04001167void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001168{
Geoff Lang2186c382016-10-14 10:54:54 -04001169 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001170}
1171
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001172Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001174 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175}
1176
Jamie Madill2f348d22017-06-05 10:50:59 -04001177FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001178{
Jamie Madill96a483b2017-06-27 16:49:21 -04001179 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180}
1181
Jamie Madill2f348d22017-06-05 10:50:59 -04001182Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001183{
Jamie Madill96a483b2017-06-27 16:49:21 -04001184 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001186 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001188
1189 Query *query = mQueryMap.query(handle);
1190 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001191 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001192 query = new Query(mImplementation->createQuery(type), handle);
1193 query->addRef();
1194 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001195 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001196 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197}
1198
Geoff Lang70d0f492015-12-10 17:45:46 -05001199Query *Context::getQuery(GLuint handle) const
1200{
Jamie Madill96a483b2017-06-27 16:49:21 -04001201 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001202}
1203
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001204Texture *Context::getTargetTexture(GLenum target) const
1205{
Ian Ewellbda75592016-04-18 17:25:54 -04001206 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001207 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001208}
1209
Geoff Lang76b10c92014-09-05 16:28:14 -04001210Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001212 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213}
1214
Geoff Lang492a7e42014-11-05 13:27:06 -05001215Compiler *Context::getCompiler() const
1216{
Jamie Madill2f348d22017-06-05 10:50:59 -04001217 if (mCompiler.get() == nullptr)
1218 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001219 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001220 }
1221 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001222}
1223
Jamie Madillc1d770e2017-04-13 17:31:24 -04001224void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225{
1226 switch (pname)
1227 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001228 case GL_SHADER_COMPILER:
1229 *params = GL_TRUE;
1230 break;
1231 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1232 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1233 break;
1234 default:
1235 mGLState.getBooleanv(pname, params);
1236 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238}
1239
Jamie Madillc1d770e2017-04-13 17:31:24 -04001240void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241{
Shannon Woods53a94a82014-06-24 15:20:36 -04001242 // Queries about context capabilities and maximums are answered by Context.
1243 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244 switch (pname)
1245 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001246 case GL_ALIASED_LINE_WIDTH_RANGE:
1247 params[0] = mCaps.minAliasedLineWidth;
1248 params[1] = mCaps.maxAliasedLineWidth;
1249 break;
1250 case GL_ALIASED_POINT_SIZE_RANGE:
1251 params[0] = mCaps.minAliasedPointSize;
1252 params[1] = mCaps.maxAliasedPointSize;
1253 break;
1254 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1255 ASSERT(mExtensions.textureFilterAnisotropic);
1256 *params = mExtensions.maxTextureAnisotropy;
1257 break;
1258 case GL_MAX_TEXTURE_LOD_BIAS:
1259 *params = mCaps.maxLODBias;
1260 break;
1261
1262 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1263 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1264 {
1265 ASSERT(mExtensions.pathRendering);
1266 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1267 memcpy(params, m, 16 * sizeof(GLfloat));
1268 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001269 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001270
Jamie Madill231c7f52017-04-26 13:45:37 -04001271 default:
1272 mGLState.getFloatv(pname, params);
1273 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275}
1276
Jamie Madillc1d770e2017-04-13 17:31:24 -04001277void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278{
Shannon Woods53a94a82014-06-24 15:20:36 -04001279 // Queries about context capabilities and maximums are answered by Context.
1280 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001281
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001282 switch (pname)
1283 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001284 case GL_MAX_VERTEX_ATTRIBS:
1285 *params = mCaps.maxVertexAttributes;
1286 break;
1287 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1288 *params = mCaps.maxVertexUniformVectors;
1289 break;
1290 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1291 *params = mCaps.maxVertexUniformComponents;
1292 break;
1293 case GL_MAX_VARYING_VECTORS:
1294 *params = mCaps.maxVaryingVectors;
1295 break;
1296 case GL_MAX_VARYING_COMPONENTS:
1297 *params = mCaps.maxVertexOutputComponents;
1298 break;
1299 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1300 *params = mCaps.maxCombinedTextureImageUnits;
1301 break;
1302 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1303 *params = mCaps.maxVertexTextureImageUnits;
1304 break;
1305 case GL_MAX_TEXTURE_IMAGE_UNITS:
1306 *params = mCaps.maxTextureImageUnits;
1307 break;
1308 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1309 *params = mCaps.maxFragmentUniformVectors;
1310 break;
1311 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1312 *params = mCaps.maxFragmentUniformComponents;
1313 break;
1314 case GL_MAX_RENDERBUFFER_SIZE:
1315 *params = mCaps.maxRenderbufferSize;
1316 break;
1317 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1318 *params = mCaps.maxColorAttachments;
1319 break;
1320 case GL_MAX_DRAW_BUFFERS_EXT:
1321 *params = mCaps.maxDrawBuffers;
1322 break;
1323 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1324 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1325 case GL_SUBPIXEL_BITS:
1326 *params = 4;
1327 break;
1328 case GL_MAX_TEXTURE_SIZE:
1329 *params = mCaps.max2DTextureSize;
1330 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001331 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1332 *params = mCaps.maxRectangleTextureSize;
1333 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001334 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1335 *params = mCaps.maxCubeMapTextureSize;
1336 break;
1337 case GL_MAX_3D_TEXTURE_SIZE:
1338 *params = mCaps.max3DTextureSize;
1339 break;
1340 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1341 *params = mCaps.maxArrayTextureLayers;
1342 break;
1343 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1344 *params = mCaps.uniformBufferOffsetAlignment;
1345 break;
1346 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1347 *params = mCaps.maxUniformBufferBindings;
1348 break;
1349 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1350 *params = mCaps.maxVertexUniformBlocks;
1351 break;
1352 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1353 *params = mCaps.maxFragmentUniformBlocks;
1354 break;
1355 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1356 *params = mCaps.maxCombinedTextureImageUnits;
1357 break;
1358 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1359 *params = mCaps.maxVertexOutputComponents;
1360 break;
1361 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1362 *params = mCaps.maxFragmentInputComponents;
1363 break;
1364 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1365 *params = mCaps.minProgramTexelOffset;
1366 break;
1367 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1368 *params = mCaps.maxProgramTexelOffset;
1369 break;
1370 case GL_MAJOR_VERSION:
1371 *params = getClientVersion().major;
1372 break;
1373 case GL_MINOR_VERSION:
1374 *params = getClientVersion().minor;
1375 break;
1376 case GL_MAX_ELEMENTS_INDICES:
1377 *params = mCaps.maxElementsIndices;
1378 break;
1379 case GL_MAX_ELEMENTS_VERTICES:
1380 *params = mCaps.maxElementsVertices;
1381 break;
1382 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1383 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1384 break;
1385 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1386 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1387 break;
1388 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1389 *params = mCaps.maxTransformFeedbackSeparateComponents;
1390 break;
1391 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1392 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1393 break;
1394 case GL_MAX_SAMPLES_ANGLE:
1395 *params = mCaps.maxSamples;
1396 break;
1397 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001398 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001399 params[0] = mCaps.maxViewportWidth;
1400 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001401 }
1402 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001403 case GL_COMPRESSED_TEXTURE_FORMATS:
1404 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1405 params);
1406 break;
1407 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1408 *params = mResetStrategy;
1409 break;
1410 case GL_NUM_SHADER_BINARY_FORMATS:
1411 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1412 break;
1413 case GL_SHADER_BINARY_FORMATS:
1414 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1415 break;
1416 case GL_NUM_PROGRAM_BINARY_FORMATS:
1417 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1418 break;
1419 case GL_PROGRAM_BINARY_FORMATS:
1420 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1421 break;
1422 case GL_NUM_EXTENSIONS:
1423 *params = static_cast<GLint>(mExtensionStrings.size());
1424 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001425
Jamie Madill231c7f52017-04-26 13:45:37 -04001426 // GL_KHR_debug
1427 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1428 *params = mExtensions.maxDebugMessageLength;
1429 break;
1430 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1431 *params = mExtensions.maxDebugLoggedMessages;
1432 break;
1433 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1434 *params = mExtensions.maxDebugGroupStackDepth;
1435 break;
1436 case GL_MAX_LABEL_LENGTH:
1437 *params = mExtensions.maxLabelLength;
1438 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001439
Martin Radeve5285d22017-07-14 16:23:53 +03001440 // GL_ANGLE_multiview
1441 case GL_MAX_VIEWS_ANGLE:
1442 *params = mExtensions.maxViews;
1443 break;
1444
Jamie Madill231c7f52017-04-26 13:45:37 -04001445 // GL_EXT_disjoint_timer_query
1446 case GL_GPU_DISJOINT_EXT:
1447 *params = mImplementation->getGPUDisjoint();
1448 break;
1449 case GL_MAX_FRAMEBUFFER_WIDTH:
1450 *params = mCaps.maxFramebufferWidth;
1451 break;
1452 case GL_MAX_FRAMEBUFFER_HEIGHT:
1453 *params = mCaps.maxFramebufferHeight;
1454 break;
1455 case GL_MAX_FRAMEBUFFER_SAMPLES:
1456 *params = mCaps.maxFramebufferSamples;
1457 break;
1458 case GL_MAX_SAMPLE_MASK_WORDS:
1459 *params = mCaps.maxSampleMaskWords;
1460 break;
1461 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1462 *params = mCaps.maxColorTextureSamples;
1463 break;
1464 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1465 *params = mCaps.maxDepthTextureSamples;
1466 break;
1467 case GL_MAX_INTEGER_SAMPLES:
1468 *params = mCaps.maxIntegerSamples;
1469 break;
1470 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1471 *params = mCaps.maxVertexAttribRelativeOffset;
1472 break;
1473 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1474 *params = mCaps.maxVertexAttribBindings;
1475 break;
1476 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1477 *params = mCaps.maxVertexAttribStride;
1478 break;
1479 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1480 *params = mCaps.maxVertexAtomicCounterBuffers;
1481 break;
1482 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1483 *params = mCaps.maxVertexAtomicCounters;
1484 break;
1485 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1486 *params = mCaps.maxVertexImageUniforms;
1487 break;
1488 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1489 *params = mCaps.maxVertexShaderStorageBlocks;
1490 break;
1491 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1492 *params = mCaps.maxFragmentAtomicCounterBuffers;
1493 break;
1494 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1495 *params = mCaps.maxFragmentAtomicCounters;
1496 break;
1497 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1498 *params = mCaps.maxFragmentImageUniforms;
1499 break;
1500 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1501 *params = mCaps.maxFragmentShaderStorageBlocks;
1502 break;
1503 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1504 *params = mCaps.minProgramTextureGatherOffset;
1505 break;
1506 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1507 *params = mCaps.maxProgramTextureGatherOffset;
1508 break;
1509 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1510 *params = mCaps.maxComputeWorkGroupInvocations;
1511 break;
1512 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1513 *params = mCaps.maxComputeUniformBlocks;
1514 break;
1515 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1516 *params = mCaps.maxComputeTextureImageUnits;
1517 break;
1518 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1519 *params = mCaps.maxComputeSharedMemorySize;
1520 break;
1521 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1522 *params = mCaps.maxComputeUniformComponents;
1523 break;
1524 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1525 *params = mCaps.maxComputeAtomicCounterBuffers;
1526 break;
1527 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1528 *params = mCaps.maxComputeAtomicCounters;
1529 break;
1530 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1531 *params = mCaps.maxComputeImageUniforms;
1532 break;
1533 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1534 *params = mCaps.maxCombinedComputeUniformComponents;
1535 break;
1536 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1537 *params = mCaps.maxComputeShaderStorageBlocks;
1538 break;
1539 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1540 *params = mCaps.maxCombinedShaderOutputResources;
1541 break;
1542 case GL_MAX_UNIFORM_LOCATIONS:
1543 *params = mCaps.maxUniformLocations;
1544 break;
1545 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1546 *params = mCaps.maxAtomicCounterBufferBindings;
1547 break;
1548 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1549 *params = mCaps.maxAtomicCounterBufferSize;
1550 break;
1551 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1552 *params = mCaps.maxCombinedAtomicCounterBuffers;
1553 break;
1554 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1555 *params = mCaps.maxCombinedAtomicCounters;
1556 break;
1557 case GL_MAX_IMAGE_UNITS:
1558 *params = mCaps.maxImageUnits;
1559 break;
1560 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1561 *params = mCaps.maxCombinedImageUniforms;
1562 break;
1563 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1564 *params = mCaps.maxShaderStorageBufferBindings;
1565 break;
1566 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1567 *params = mCaps.maxCombinedShaderStorageBlocks;
1568 break;
1569 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1570 *params = mCaps.shaderStorageBufferOffsetAlignment;
1571 break;
1572 default:
1573 mGLState.getIntegerv(this, pname, params);
1574 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001575 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001576}
1577
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001578void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001579{
Shannon Woods53a94a82014-06-24 15:20:36 -04001580 // Queries about context capabilities and maximums are answered by Context.
1581 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001582 switch (pname)
1583 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001584 case GL_MAX_ELEMENT_INDEX:
1585 *params = mCaps.maxElementIndex;
1586 break;
1587 case GL_MAX_UNIFORM_BLOCK_SIZE:
1588 *params = mCaps.maxUniformBlockSize;
1589 break;
1590 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1591 *params = mCaps.maxCombinedVertexUniformComponents;
1592 break;
1593 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1594 *params = mCaps.maxCombinedFragmentUniformComponents;
1595 break;
1596 case GL_MAX_SERVER_WAIT_TIMEOUT:
1597 *params = mCaps.maxServerWaitTimeout;
1598 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001599
Jamie Madill231c7f52017-04-26 13:45:37 -04001600 // GL_EXT_disjoint_timer_query
1601 case GL_TIMESTAMP_EXT:
1602 *params = mImplementation->getTimestamp();
1603 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001604
Jamie Madill231c7f52017-04-26 13:45:37 -04001605 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1606 *params = mCaps.maxShaderStorageBlockSize;
1607 break;
1608 default:
1609 UNREACHABLE();
1610 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001611 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001612}
1613
Geoff Lang70d0f492015-12-10 17:45:46 -05001614void Context::getPointerv(GLenum pname, void **params) const
1615{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001616 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001617}
1618
Martin Radev66fb8202016-07-28 11:45:20 +03001619void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001620{
Shannon Woods53a94a82014-06-24 15:20:36 -04001621 // Queries about context capabilities and maximums are answered by Context.
1622 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001623
1624 GLenum nativeType;
1625 unsigned int numParams;
1626 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1627 ASSERT(queryStatus);
1628
1629 if (nativeType == GL_INT)
1630 {
1631 switch (target)
1632 {
1633 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1634 ASSERT(index < 3u);
1635 *data = mCaps.maxComputeWorkGroupCount[index];
1636 break;
1637 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1638 ASSERT(index < 3u);
1639 *data = mCaps.maxComputeWorkGroupSize[index];
1640 break;
1641 default:
1642 mGLState.getIntegeri_v(target, index, data);
1643 }
1644 }
1645 else
1646 {
1647 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1648 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001649}
1650
Martin Radev66fb8202016-07-28 11:45:20 +03001651void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001652{
Shannon Woods53a94a82014-06-24 15:20:36 -04001653 // Queries about context capabilities and maximums are answered by Context.
1654 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001655
1656 GLenum nativeType;
1657 unsigned int numParams;
1658 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1659 ASSERT(queryStatus);
1660
1661 if (nativeType == GL_INT_64_ANGLEX)
1662 {
1663 mGLState.getInteger64i_v(target, index, data);
1664 }
1665 else
1666 {
1667 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1668 }
1669}
1670
1671void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1672{
1673 // Queries about context capabilities and maximums are answered by Context.
1674 // Queries about current GL state values are answered by State.
1675
1676 GLenum nativeType;
1677 unsigned int numParams;
1678 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1679 ASSERT(queryStatus);
1680
1681 if (nativeType == GL_BOOL)
1682 {
1683 mGLState.getBooleani_v(target, index, data);
1684 }
1685 else
1686 {
1687 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1688 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001689}
1690
He Yunchao010e4db2017-03-03 14:22:06 +08001691void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1692{
1693 Buffer *buffer = mGLState.getTargetBuffer(target);
1694 QueryBufferParameteriv(buffer, pname, params);
1695}
1696
1697void Context::getFramebufferAttachmentParameteriv(GLenum target,
1698 GLenum attachment,
1699 GLenum pname,
1700 GLint *params)
1701{
1702 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1703 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1704}
1705
1706void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1707{
1708 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1709 QueryRenderbufferiv(this, renderbuffer, pname, params);
1710}
1711
1712void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1713{
1714 Texture *texture = getTargetTexture(target);
1715 QueryTexParameterfv(texture, pname, params);
1716}
1717
1718void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1719{
1720 Texture *texture = getTargetTexture(target);
1721 QueryTexParameteriv(texture, pname, params);
1722}
1723void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1724{
1725 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001726 SetTexParameterf(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001727 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001728}
1729
1730void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1731{
1732 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001733 SetTexParameterfv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001734 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001735}
1736
1737void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1738{
1739 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001740 SetTexParameteri(this, texture, pname, param);
Jamie Madill81c2e252017-09-09 23:32:46 -04001741 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001742}
1743
1744void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1745{
1746 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001747 SetTexParameteriv(this, texture, pname, params);
Jamie Madill81c2e252017-09-09 23:32:46 -04001748 onTextureChange(texture);
He Yunchao010e4db2017-03-03 14:22:06 +08001749}
1750
Jamie Madill675fe712016-12-19 13:07:54 -05001751void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001752{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001753 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001754 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1755 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001756}
1757
Jamie Madill675fe712016-12-19 13:07:54 -05001758void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001759{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001760 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001761 ANGLE_CONTEXT_TRY(
1762 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1763 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001764}
1765
Jamie Madill876429b2017-04-20 15:46:24 -04001766void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001767{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001768 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001769 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001770}
1771
Jamie Madill675fe712016-12-19 13:07:54 -05001772void Context::drawElementsInstanced(GLenum mode,
1773 GLsizei count,
1774 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001775 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001776 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001777{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001778 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001779 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001780 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001781}
1782
Jamie Madill675fe712016-12-19 13:07:54 -05001783void Context::drawRangeElements(GLenum mode,
1784 GLuint start,
1785 GLuint end,
1786 GLsizei count,
1787 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001788 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001789{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001790 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001791 ANGLE_CONTEXT_TRY(
1792 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001793}
1794
Jamie Madill876429b2017-04-20 15:46:24 -04001795void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001796{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001797 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001798 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001799}
1800
Jamie Madill876429b2017-04-20 15:46:24 -04001801void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001802{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001803 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001804 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001805}
1806
Jamie Madill675fe712016-12-19 13:07:54 -05001807void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001808{
Jamie Madill675fe712016-12-19 13:07:54 -05001809 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001810}
1811
Jamie Madill675fe712016-12-19 13:07:54 -05001812void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001813{
Jamie Madill675fe712016-12-19 13:07:54 -05001814 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001815}
1816
Austin Kinross6ee1e782015-05-29 17:05:37 -07001817void Context::insertEventMarker(GLsizei length, const char *marker)
1818{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001819 ASSERT(mImplementation);
1820 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001821}
1822
1823void Context::pushGroupMarker(GLsizei length, const char *marker)
1824{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001825 ASSERT(mImplementation);
1826 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001827}
1828
1829void Context::popGroupMarker()
1830{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001831 ASSERT(mImplementation);
1832 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001833}
1834
Geoff Langd8605522016-04-13 10:19:12 -04001835void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1836{
1837 Program *programObject = getProgram(program);
1838 ASSERT(programObject);
1839
1840 programObject->bindUniformLocation(location, name);
1841}
1842
Sami Väisänena797e062016-05-12 15:23:40 +03001843void Context::setCoverageModulation(GLenum components)
1844{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001845 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001846}
1847
Sami Väisänene45e53b2016-05-25 10:36:04 +03001848void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1849{
1850 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1851}
1852
1853void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1854{
1855 GLfloat I[16];
1856 angle::Matrix<GLfloat>::setToIdentity(I);
1857
1858 mGLState.loadPathRenderingMatrix(matrixMode, I);
1859}
1860
1861void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1862{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001863 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001864 if (!pathObj)
1865 return;
1866
1867 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1868 syncRendererState();
1869
1870 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1871}
1872
1873void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1874{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001875 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001876 if (!pathObj)
1877 return;
1878
1879 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1880 syncRendererState();
1881
1882 mImplementation->stencilStrokePath(pathObj, reference, mask);
1883}
1884
1885void Context::coverFillPath(GLuint path, GLenum coverMode)
1886{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001887 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001888 if (!pathObj)
1889 return;
1890
1891 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1892 syncRendererState();
1893
1894 mImplementation->coverFillPath(pathObj, coverMode);
1895}
1896
1897void Context::coverStrokePath(GLuint path, GLenum coverMode)
1898{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001899 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001900 if (!pathObj)
1901 return;
1902
1903 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1904 syncRendererState();
1905
1906 mImplementation->coverStrokePath(pathObj, coverMode);
1907}
1908
1909void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1910{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001911 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001912 if (!pathObj)
1913 return;
1914
1915 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1916 syncRendererState();
1917
1918 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1919}
1920
1921void Context::stencilThenCoverStrokePath(GLuint path,
1922 GLint reference,
1923 GLuint mask,
1924 GLenum coverMode)
1925{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001926 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001927 if (!pathObj)
1928 return;
1929
1930 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1931 syncRendererState();
1932
1933 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1934}
1935
Sami Väisänend59ca052016-06-21 16:10:00 +03001936void Context::coverFillPathInstanced(GLsizei numPaths,
1937 GLenum pathNameType,
1938 const void *paths,
1939 GLuint pathBase,
1940 GLenum coverMode,
1941 GLenum transformType,
1942 const GLfloat *transformValues)
1943{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001944 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001945
1946 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1947 syncRendererState();
1948
1949 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1950}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001951
Sami Väisänend59ca052016-06-21 16:10:00 +03001952void Context::coverStrokePathInstanced(GLsizei numPaths,
1953 GLenum pathNameType,
1954 const void *paths,
1955 GLuint pathBase,
1956 GLenum coverMode,
1957 GLenum transformType,
1958 const GLfloat *transformValues)
1959{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001960 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001961
1962 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1963 syncRendererState();
1964
1965 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1966 transformValues);
1967}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001968
Sami Väisänend59ca052016-06-21 16:10:00 +03001969void Context::stencilFillPathInstanced(GLsizei numPaths,
1970 GLenum pathNameType,
1971 const void *paths,
1972 GLuint pathBase,
1973 GLenum fillMode,
1974 GLuint mask,
1975 GLenum transformType,
1976 const GLfloat *transformValues)
1977{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001978 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001979
1980 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1981 syncRendererState();
1982
1983 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1984 transformValues);
1985}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001986
Sami Väisänend59ca052016-06-21 16:10:00 +03001987void Context::stencilStrokePathInstanced(GLsizei numPaths,
1988 GLenum pathNameType,
1989 const void *paths,
1990 GLuint pathBase,
1991 GLint reference,
1992 GLuint mask,
1993 GLenum transformType,
1994 const GLfloat *transformValues)
1995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001996 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001997
1998 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1999 syncRendererState();
2000
2001 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2002 transformValues);
2003}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002004
Sami Väisänend59ca052016-06-21 16:10:00 +03002005void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2006 GLenum pathNameType,
2007 const void *paths,
2008 GLuint pathBase,
2009 GLenum fillMode,
2010 GLuint mask,
2011 GLenum coverMode,
2012 GLenum transformType,
2013 const GLfloat *transformValues)
2014{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002015 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002016
2017 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2018 syncRendererState();
2019
2020 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2021 transformType, transformValues);
2022}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002023
Sami Väisänend59ca052016-06-21 16:10:00 +03002024void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2025 GLenum pathNameType,
2026 const void *paths,
2027 GLuint pathBase,
2028 GLint reference,
2029 GLuint mask,
2030 GLenum coverMode,
2031 GLenum transformType,
2032 const GLfloat *transformValues)
2033{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002034 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002035
2036 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2037 syncRendererState();
2038
2039 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2040 transformType, transformValues);
2041}
2042
Sami Väisänen46eaa942016-06-29 10:26:37 +03002043void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2044{
2045 auto *programObject = getProgram(program);
2046
2047 programObject->bindFragmentInputLocation(location, name);
2048}
2049
2050void Context::programPathFragmentInputGen(GLuint program,
2051 GLint location,
2052 GLenum genMode,
2053 GLint components,
2054 const GLfloat *coeffs)
2055{
2056 auto *programObject = getProgram(program);
2057
Jamie Madillbd044ed2017-06-05 12:59:21 -04002058 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002059}
2060
jchen1015015f72017-03-16 13:54:21 +08002061GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2062{
jchen10fd7c3b52017-03-21 15:36:03 +08002063 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002064 return QueryProgramResourceIndex(programObject, programInterface, name);
2065}
2066
jchen10fd7c3b52017-03-21 15:36:03 +08002067void Context::getProgramResourceName(GLuint program,
2068 GLenum programInterface,
2069 GLuint index,
2070 GLsizei bufSize,
2071 GLsizei *length,
2072 GLchar *name)
2073{
2074 const auto *programObject = getProgram(program);
2075 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2076}
2077
jchen10191381f2017-04-11 13:59:04 +08002078GLint Context::getProgramResourceLocation(GLuint program,
2079 GLenum programInterface,
2080 const GLchar *name)
2081{
2082 const auto *programObject = getProgram(program);
2083 return QueryProgramResourceLocation(programObject, programInterface, name);
2084}
2085
jchen10880683b2017-04-12 16:21:55 +08002086void Context::getProgramResourceiv(GLuint program,
2087 GLenum programInterface,
2088 GLuint index,
2089 GLsizei propCount,
2090 const GLenum *props,
2091 GLsizei bufSize,
2092 GLsizei *length,
2093 GLint *params)
2094{
2095 const auto *programObject = getProgram(program);
2096 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2097 length, params);
2098}
2099
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002100Error Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002101{
Geoff Langda5777c2014-07-11 09:52:58 -04002102 if (error.isError())
2103 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002104 GLenum code = error.getCode();
2105 mErrors.insert(code);
2106 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2107 {
2108 markContextLost();
2109 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002110
2111 if (!error.getMessage().empty())
2112 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002113 auto *debug = &mGLState.getDebug();
2114 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2115 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002116 }
Geoff Langda5777c2014-07-11 09:52:58 -04002117 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002118
2119 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002120}
2121
2122// Get one of the recorded errors and clear its flag, if any.
2123// [OpenGL ES 2.0.24] section 2.5 page 13.
2124GLenum Context::getError()
2125{
Geoff Langda5777c2014-07-11 09:52:58 -04002126 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002127 {
Geoff Langda5777c2014-07-11 09:52:58 -04002128 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002129 }
Geoff Langda5777c2014-07-11 09:52:58 -04002130 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002131 {
Geoff Langda5777c2014-07-11 09:52:58 -04002132 GLenum error = *mErrors.begin();
2133 mErrors.erase(mErrors.begin());
2134 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002135 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002136}
2137
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002138// NOTE: this function should not assume that this context is current!
2139void Context::markContextLost()
2140{
2141 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002142 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002143 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002144 mContextLostForced = true;
2145 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002146 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002147}
2148
2149bool Context::isContextLost()
2150{
2151 return mContextLost;
2152}
2153
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002154GLenum Context::getResetStatus()
2155{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002156 // Even if the application doesn't want to know about resets, we want to know
2157 // as it will allow us to skip all the calls.
2158 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002159 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002160 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002161 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002162 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002163 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002164
2165 // EXT_robustness, section 2.6: If the reset notification behavior is
2166 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2167 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2168 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002169 }
2170
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002171 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2172 // status should be returned at least once, and GL_NO_ERROR should be returned
2173 // once the device has finished resetting.
2174 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002175 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002176 ASSERT(mResetStatus == GL_NO_ERROR);
2177 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002178
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002179 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002180 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002181 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002182 }
2183 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002184 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002185 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002186 // If markContextLost was used to mark the context lost then
2187 // assume that is not recoverable, and continue to report the
2188 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002189 mResetStatus = mImplementation->getResetStatus();
2190 }
Jamie Madill893ab082014-05-16 16:56:10 -04002191
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002192 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002193}
2194
2195bool Context::isResetNotificationEnabled()
2196{
2197 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2198}
2199
Corentin Walleze3b10e82015-05-20 11:06:25 -04002200const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002201{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002202 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002203}
2204
2205EGLenum Context::getClientType() const
2206{
2207 return mClientType;
2208}
2209
2210EGLenum Context::getRenderBuffer() const
2211{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002212 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2213 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002214 {
2215 return EGL_NONE;
2216 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002217
2218 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2219 ASSERT(backAttachment != nullptr);
2220 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002221}
2222
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002223VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002224{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002225 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002226 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2227 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002228 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002229 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2230 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002231
Jamie Madill96a483b2017-06-27 16:49:21 -04002232 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002233 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002234
2235 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002236}
2237
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002238TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002239{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002240 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002241 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2242 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002243 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002244 transformFeedback =
2245 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002246 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002247 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002248 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002249
2250 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002251}
2252
2253bool Context::isVertexArrayGenerated(GLuint vertexArray)
2254{
Jamie Madill96a483b2017-06-27 16:49:21 -04002255 ASSERT(mVertexArrayMap.contains(0));
2256 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002257}
2258
2259bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2260{
Jamie Madill96a483b2017-06-27 16:49:21 -04002261 ASSERT(mTransformFeedbackMap.contains(0));
2262 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002263}
2264
Shannon Woods53a94a82014-06-24 15:20:36 -04002265void Context::detachTexture(GLuint texture)
2266{
2267 // Simple pass-through to State's detachTexture method, as textures do not require
2268 // allocation map management either here or in the resource manager at detach time.
2269 // Zero textures are held by the Context, and we don't attempt to request them from
2270 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002271 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002272}
2273
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002274void Context::detachBuffer(GLuint buffer)
2275{
Yuly Novikov5807a532015-12-03 13:01:22 -05002276 // Simple pass-through to State's detachBuffer method, since
2277 // only buffer attachments to container objects that are bound to the current context
2278 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002279
Yuly Novikov5807a532015-12-03 13:01:22 -05002280 // [OpenGL ES 3.2] section 5.1.2 page 45:
2281 // Attachments to unbound container objects, such as
2282 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2283 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002284 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002285}
2286
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002287void Context::detachFramebuffer(GLuint framebuffer)
2288{
Shannon Woods53a94a82014-06-24 15:20:36 -04002289 // Framebuffer detachment is handled by Context, because 0 is a valid
2290 // Framebuffer object, and a pointer to it must be passed from Context
2291 // to State at binding time.
2292
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002293 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002294 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2295 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2296 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002297
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002298 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002299 {
2300 bindReadFramebuffer(0);
2301 }
2302
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002303 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002304 {
2305 bindDrawFramebuffer(0);
2306 }
2307}
2308
2309void Context::detachRenderbuffer(GLuint renderbuffer)
2310{
Jamie Madilla02315b2017-02-23 14:14:47 -05002311 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002312}
2313
Jamie Madill57a89722013-07-02 11:57:03 -04002314void Context::detachVertexArray(GLuint vertexArray)
2315{
Jamie Madill77a72f62015-04-14 11:18:32 -04002316 // Vertex array detachment is handled by Context, because 0 is a valid
2317 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002318 // binding time.
2319
Jamie Madill57a89722013-07-02 11:57:03 -04002320 // [OpenGL ES 3.0.2] section 2.10 page 43:
2321 // If a vertex array object that is currently bound is deleted, the binding
2322 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002323 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002324 {
2325 bindVertexArray(0);
2326 }
2327}
2328
Geoff Langc8058452014-02-03 12:04:11 -05002329void Context::detachTransformFeedback(GLuint transformFeedback)
2330{
Corentin Walleza2257da2016-04-19 16:43:12 -04002331 // Transform feedback detachment is handled by Context, because 0 is a valid
2332 // transform feedback, and a pointer to it must be passed from Context to State at
2333 // binding time.
2334
2335 // The OpenGL specification doesn't mention what should happen when the currently bound
2336 // transform feedback object is deleted. Since it is a container object, we treat it like
2337 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002338 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002339 {
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04002340 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Corentin Walleza2257da2016-04-19 16:43:12 -04002341 }
Geoff Langc8058452014-02-03 12:04:11 -05002342}
2343
Jamie Madilldc356042013-07-19 16:36:57 -04002344void Context::detachSampler(GLuint sampler)
2345{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002346 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002347}
2348
Jamie Madill3ef140a2017-08-26 23:11:21 -04002349void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002350{
Shaodde78e82017-05-22 14:13:27 +08002351 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002352}
2353
Jamie Madille29d1672013-07-19 16:36:57 -04002354void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2355{
Geoff Langc1984ed2016-10-07 12:41:00 -04002356 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002357 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002358 SetSamplerParameteri(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002359 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002360}
Jamie Madille29d1672013-07-19 16:36:57 -04002361
Geoff Langc1984ed2016-10-07 12:41:00 -04002362void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2363{
2364 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002365 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002366 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002367 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002368}
2369
2370void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2371{
Geoff Langc1984ed2016-10-07 12:41:00 -04002372 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002373 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002374 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002375 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madille29d1672013-07-19 16:36:57 -04002376}
2377
Geoff Langc1984ed2016-10-07 12:41:00 -04002378void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002379{
Geoff Langc1984ed2016-10-07 12:41:00 -04002380 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002381 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002382 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002383 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002384}
2385
Geoff Langc1984ed2016-10-07 12:41:00 -04002386void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002387{
Geoff Langc1984ed2016-10-07 12:41:00 -04002388 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002389 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002390 QuerySamplerParameteriv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002391 mGLState.setObjectDirty(GL_SAMPLER);
Geoff Langc1984ed2016-10-07 12:41:00 -04002392}
Jamie Madill9675b802013-07-19 16:36:59 -04002393
Geoff Langc1984ed2016-10-07 12:41:00 -04002394void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2395{
2396 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002397 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002398 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002399 mGLState.setObjectDirty(GL_SAMPLER);
Jamie Madill9675b802013-07-19 16:36:59 -04002400}
2401
Olli Etuahof0fee072016-03-30 15:11:58 +03002402void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2403{
2404 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002405 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002406}
2407
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002408void Context::initRendererString()
2409{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002410 std::ostringstream rendererString;
2411 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002412 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002413 rendererString << ")";
2414
Geoff Langcec35902014-04-16 10:52:36 -04002415 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002416}
2417
Geoff Langc339c4e2016-11-29 10:37:36 -05002418void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002419{
Geoff Langc339c4e2016-11-29 10:37:36 -05002420 const Version &clientVersion = getClientVersion();
2421
2422 std::ostringstream versionString;
2423 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2424 << ANGLE_VERSION_STRING << ")";
2425 mVersionString = MakeStaticString(versionString.str());
2426
2427 std::ostringstream shadingLanguageVersionString;
2428 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2429 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2430 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2431 << ")";
2432 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002433}
2434
Geoff Langcec35902014-04-16 10:52:36 -04002435void Context::initExtensionStrings()
2436{
Geoff Langc339c4e2016-11-29 10:37:36 -05002437 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2438 std::ostringstream combinedStringStream;
2439 std::copy(strings.begin(), strings.end(),
2440 std::ostream_iterator<const char *>(combinedStringStream, " "));
2441 return MakeStaticString(combinedStringStream.str());
2442 };
2443
2444 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002445 for (const auto &extensionString : mExtensions.getStrings())
2446 {
2447 mExtensionStrings.push_back(MakeStaticString(extensionString));
2448 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002449 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002450
Bryan Bernhart58806562017-01-05 13:09:31 -08002451 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2452
Geoff Langc339c4e2016-11-29 10:37:36 -05002453 mRequestableExtensionStrings.clear();
2454 for (const auto &extensionInfo : GetExtensionInfoMap())
2455 {
2456 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002457 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2458 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002459 {
2460 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2461 }
2462 }
2463 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002464}
2465
Geoff Langc339c4e2016-11-29 10:37:36 -05002466const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002467{
Geoff Langc339c4e2016-11-29 10:37:36 -05002468 switch (name)
2469 {
2470 case GL_VENDOR:
2471 return reinterpret_cast<const GLubyte *>("Google Inc.");
2472
2473 case GL_RENDERER:
2474 return reinterpret_cast<const GLubyte *>(mRendererString);
2475
2476 case GL_VERSION:
2477 return reinterpret_cast<const GLubyte *>(mVersionString);
2478
2479 case GL_SHADING_LANGUAGE_VERSION:
2480 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2481
2482 case GL_EXTENSIONS:
2483 return reinterpret_cast<const GLubyte *>(mExtensionString);
2484
2485 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2486 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2487
2488 default:
2489 UNREACHABLE();
2490 return nullptr;
2491 }
Geoff Langcec35902014-04-16 10:52:36 -04002492}
2493
Geoff Langc339c4e2016-11-29 10:37:36 -05002494const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002495{
Geoff Langc339c4e2016-11-29 10:37:36 -05002496 switch (name)
2497 {
2498 case GL_EXTENSIONS:
2499 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2500
2501 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2502 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2503
2504 default:
2505 UNREACHABLE();
2506 return nullptr;
2507 }
Geoff Langcec35902014-04-16 10:52:36 -04002508}
2509
2510size_t Context::getExtensionStringCount() const
2511{
2512 return mExtensionStrings.size();
2513}
2514
Geoff Langc339c4e2016-11-29 10:37:36 -05002515void Context::requestExtension(const char *name)
2516{
2517 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2518 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2519 const auto &extension = extensionInfos.at(name);
2520 ASSERT(extension.Requestable);
2521
2522 if (mExtensions.*(extension.ExtensionsMember))
2523 {
2524 // Extension already enabled
2525 return;
2526 }
2527
2528 mExtensions.*(extension.ExtensionsMember) = true;
2529 updateCaps();
2530 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002531
Jamie Madill2f348d22017-06-05 10:50:59 -04002532 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2533 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002534
Jamie Madill81c2e252017-09-09 23:32:46 -04002535 // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
2536 // sampleable.
2537 mState.mTextures->signalAllTexturesDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002538 for (auto &zeroTexture : mZeroTextures)
2539 {
Jamie Madill81c2e252017-09-09 23:32:46 -04002540 zeroTexture.second->signalDirty();
Geoff Lang9aded172017-04-05 11:07:56 -04002541 }
2542
2543 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002544}
2545
2546size_t Context::getRequestableExtensionStringCount() const
2547{
2548 return mRequestableExtensionStrings.size();
2549}
2550
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002551void Context::beginTransformFeedback(GLenum primitiveMode)
2552{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002553 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002554 ASSERT(transformFeedback != nullptr);
2555 ASSERT(!transformFeedback->isPaused());
2556
Jamie Madill6c1f6712017-02-14 19:08:04 -05002557 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002558}
2559
2560bool Context::hasActiveTransformFeedback(GLuint program) const
2561{
2562 for (auto pair : mTransformFeedbackMap)
2563 {
2564 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2565 {
2566 return true;
2567 }
2568 }
2569 return false;
2570}
2571
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002572void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002573{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002574 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002575
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002576 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002577
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002578 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002579
Geoff Langeb66a6e2016-10-31 13:06:12 -04002580 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002581 {
2582 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002583 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002584 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002585 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002586 mExtensions.multiview = false;
2587 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002588 }
2589
Geoff Langeb66a6e2016-10-31 13:06:12 -04002590 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002591 {
2592 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002593 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002594 }
2595
Jamie Madill00ed7a12016-05-19 13:13:38 -04002596 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002597 mExtensions.bindUniformLocation = true;
2598 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002599 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002600 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002601 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002602
2603 // Enable the no error extension if the context was created with the flag.
2604 mExtensions.noError = mSkipValidation;
2605
Corentin Wallezccab69d2017-01-27 16:57:15 -05002606 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002607 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002608
Geoff Lang70d0f492015-12-10 17:45:46 -05002609 // Explicitly enable GL_KHR_debug
2610 mExtensions.debug = true;
2611 mExtensions.maxDebugMessageLength = 1024;
2612 mExtensions.maxDebugLoggedMessages = 1024;
2613 mExtensions.maxDebugGroupStackDepth = 1024;
2614 mExtensions.maxLabelLength = 1024;
2615
Geoff Langff5b2d52016-09-07 11:32:23 -04002616 // Explicitly enable GL_ANGLE_robust_client_memory
2617 mExtensions.robustClientMemory = true;
2618
Jamie Madille08a1d32017-03-07 17:24:06 -05002619 // Determine robust resource init availability from EGL.
2620 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002621 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002622
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08002623 // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
2624 // supports it.
2625 mExtensions.robustBufferAccessBehavior =
2626 mRobustAccess && mExtensions.robustBufferAccessBehavior;
2627
Jamie Madillc43be722017-07-13 16:22:14 -04002628 // Enable the cache control query unconditionally.
2629 mExtensions.programCacheControl = true;
2630
Geoff Lang301d1612014-07-09 10:34:37 -04002631 // Apply implementation limits
2632 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002633 mCaps.maxVertexAttribBindings =
2634 getClientVersion() < ES_3_1
2635 ? mCaps.maxVertexAttributes
2636 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2637
Jamie Madill231c7f52017-04-26 13:45:37 -04002638 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2639 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2640 mCaps.maxVertexOutputComponents =
2641 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002642
Jamie Madill231c7f52017-04-26 13:45:37 -04002643 mCaps.maxFragmentInputComponents =
2644 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002645
Geoff Langc287ea62016-09-16 14:46:51 -04002646 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002647 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002648 for (const auto &extensionInfo : GetExtensionInfoMap())
2649 {
2650 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002651 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002652 {
2653 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2654 }
2655 }
2656
2657 // Generate texture caps
2658 updateCaps();
2659}
2660
2661void Context::updateCaps()
2662{
Geoff Lang900013c2014-07-07 11:32:19 -04002663 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002664 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002665
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002666 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002667 {
Geoff Langca271392017-04-05 12:30:00 -04002668 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002669 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002670
Geoff Langca271392017-04-05 12:30:00 -04002671 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002672
Geoff Lang0d8b7242015-09-09 14:56:53 -04002673 // Update the format caps based on the client version and extensions.
2674 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2675 // ES3.
2676 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002677 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002678 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002679 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002680 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002681 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002682
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002683 // OpenGL ES does not support multisampling with non-rendererable formats
2684 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002685 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002686 (getClientVersion() < ES_3_1 &&
2687 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002688 {
Geoff Langd87878e2014-09-19 15:42:59 -04002689 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002690 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002691 else
2692 {
2693 // We may have limited the max samples for some required renderbuffer formats due to
2694 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2695 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2696
2697 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2698 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2699 // exception of signed and unsigned integer formats."
2700 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2701 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2702 {
2703 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2704 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2705 }
2706
2707 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2708 if (getClientVersion() >= ES_3_1)
2709 {
2710 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2711 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2712 // the exception that the signed and unsigned integer formats are required only to
2713 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2714 // multisamples, which must be at least one."
2715 if (formatInfo.componentType == GL_INT ||
2716 formatInfo.componentType == GL_UNSIGNED_INT)
2717 {
2718 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2719 }
2720
2721 // GLES 3.1 section 19.3.1.
2722 if (formatCaps.texturable)
2723 {
2724 if (formatInfo.depthBits > 0)
2725 {
2726 mCaps.maxDepthTextureSamples =
2727 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2728 }
2729 else if (formatInfo.redBits > 0)
2730 {
2731 mCaps.maxColorTextureSamples =
2732 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2733 }
2734 }
2735 }
2736 }
Geoff Langd87878e2014-09-19 15:42:59 -04002737
2738 if (formatCaps.texturable && formatInfo.compressed)
2739 {
Geoff Langca271392017-04-05 12:30:00 -04002740 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002741 }
2742
Geoff Langca271392017-04-05 12:30:00 -04002743 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002744 }
Jamie Madill32447362017-06-28 14:53:52 -04002745
2746 // If program binary is disabled, blank out the memory cache pointer.
2747 if (!mImplementation->getNativeExtensions().getProgramBinary)
2748 {
2749 mMemoryProgramCache = nullptr;
2750 }
Geoff Lang493daf52014-07-03 13:38:44 -04002751}
2752
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002753void Context::initWorkarounds()
2754{
Jamie Madill761b02c2017-06-23 16:27:06 -04002755 // Apply back-end workarounds.
2756 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2757
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002758 // Lose the context upon out of memory error if the application is
2759 // expecting to watch for those events.
2760 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2761}
2762
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002763Error Context::prepareForDraw(GLenum drawMode)
Jamie Madillb6664922017-07-25 12:55:04 -04002764{
2765 syncRendererState();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002766
2767 InfoLog infoLog;
2768 Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
2769 mMemoryProgramCache, drawMode);
Jamie Madilla836b462017-08-16 14:58:35 -04002770 if (err.isError() || infoLog.getLength() > 0)
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002771 {
2772 WARN() << "Dynamic recompilation error log: " << infoLog.str();
2773 }
2774 return err;
Jamie Madillb6664922017-07-25 12:55:04 -04002775}
2776
Jamie Madill1b94d432015-08-07 13:23:23 -04002777void Context::syncRendererState()
2778{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002779 mGLState.syncDirtyObjects(this);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002780 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002781 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002782 mGLState.clearDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -04002783}
2784
Jamie Madillad9f24e2016-02-12 09:27:24 -05002785void Context::syncRendererState(const State::DirtyBits &bitMask,
2786 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002787{
Jamie Madill7d1f5c62017-09-02 15:32:15 -04002788 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002789 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002790 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002791 mGLState.clearDirtyBits(dirtyBits);
Jamie Madill1b94d432015-08-07 13:23:23 -04002792}
Jamie Madillc29968b2016-01-20 11:17:23 -05002793
2794void Context::blitFramebuffer(GLint srcX0,
2795 GLint srcY0,
2796 GLint srcX1,
2797 GLint srcY1,
2798 GLint dstX0,
2799 GLint dstY0,
2800 GLint dstX1,
2801 GLint dstY1,
2802 GLbitfield mask,
2803 GLenum filter)
2804{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002805 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002806 ASSERT(drawFramebuffer);
2807
2808 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2809 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2810
Jamie Madillad9f24e2016-02-12 09:27:24 -05002811 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002812
Jamie Madillc564c072017-06-01 12:45:42 -04002813 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002814}
Jamie Madillc29968b2016-01-20 11:17:23 -05002815
2816void Context::clear(GLbitfield mask)
2817{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002818 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002819 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002820}
2821
2822void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2823{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002824 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002825 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002826}
2827
2828void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2829{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002830 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002831 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002832}
2833
2834void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2835{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002836 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002837 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002838}
2839
2840void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2841{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002842 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002843 ASSERT(framebufferObject);
2844
2845 // If a buffer is not present, the clear has no effect
2846 if (framebufferObject->getDepthbuffer() == nullptr &&
2847 framebufferObject->getStencilbuffer() == nullptr)
2848 {
2849 return;
2850 }
2851
Jamie Madillad9f24e2016-02-12 09:27:24 -05002852 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002853 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002854}
2855
2856void Context::readPixels(GLint x,
2857 GLint y,
2858 GLsizei width,
2859 GLsizei height,
2860 GLenum format,
2861 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002862 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002863{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002864 if (width == 0 || height == 0)
2865 {
2866 return;
2867 }
2868
Jamie Madillad9f24e2016-02-12 09:27:24 -05002869 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002870
Jamie Madillb6664922017-07-25 12:55:04 -04002871 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2872 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002873
2874 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002875 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002876}
2877
2878void Context::copyTexImage2D(GLenum target,
2879 GLint level,
2880 GLenum internalformat,
2881 GLint x,
2882 GLint y,
2883 GLsizei width,
2884 GLsizei height,
2885 GLint border)
2886{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002887 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002888 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002889
Jamie Madillc29968b2016-01-20 11:17:23 -05002890 Rectangle sourceArea(x, y, width, height);
2891
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002892 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002893 Texture *texture =
2894 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002895 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002896}
2897
2898void Context::copyTexSubImage2D(GLenum target,
2899 GLint level,
2900 GLint xoffset,
2901 GLint yoffset,
2902 GLint x,
2903 GLint y,
2904 GLsizei width,
2905 GLsizei height)
2906{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002907 if (width == 0 || height == 0)
2908 {
2909 return;
2910 }
2911
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002912 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002913 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002914
Jamie Madillc29968b2016-01-20 11:17:23 -05002915 Offset destOffset(xoffset, yoffset, 0);
2916 Rectangle sourceArea(x, y, width, height);
2917
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002918 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002919 Texture *texture =
2920 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002921 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002922}
2923
2924void Context::copyTexSubImage3D(GLenum target,
2925 GLint level,
2926 GLint xoffset,
2927 GLint yoffset,
2928 GLint zoffset,
2929 GLint x,
2930 GLint y,
2931 GLsizei width,
2932 GLsizei height)
2933{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002934 if (width == 0 || height == 0)
2935 {
2936 return;
2937 }
2938
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002939 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002940 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002941
Jamie Madillc29968b2016-01-20 11:17:23 -05002942 Offset destOffset(xoffset, yoffset, zoffset);
2943 Rectangle sourceArea(x, y, width, height);
2944
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002945 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002946 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002947 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002948}
2949
2950void Context::framebufferTexture2D(GLenum target,
2951 GLenum attachment,
2952 GLenum textarget,
2953 GLuint texture,
2954 GLint level)
2955{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002956 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002957 ASSERT(framebuffer);
2958
2959 if (texture != 0)
2960 {
2961 Texture *textureObj = getTexture(texture);
2962
2963 ImageIndex index = ImageIndex::MakeInvalid();
2964
2965 if (textarget == GL_TEXTURE_2D)
2966 {
2967 index = ImageIndex::Make2D(level);
2968 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002969 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
2970 {
2971 index = ImageIndex::MakeRectangle(level);
2972 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002973 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2974 {
2975 ASSERT(level == 0);
2976 index = ImageIndex::Make2DMultisample();
2977 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002978 else
2979 {
2980 ASSERT(IsCubeMapTextureTarget(textarget));
2981 index = ImageIndex::MakeCube(textarget, level);
2982 }
2983
Jamie Madilla02315b2017-02-23 14:14:47 -05002984 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002985 }
2986 else
2987 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002988 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002989 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002990
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002991 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002992}
2993
2994void Context::framebufferRenderbuffer(GLenum target,
2995 GLenum attachment,
2996 GLenum renderbuffertarget,
2997 GLuint renderbuffer)
2998{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002999 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003000 ASSERT(framebuffer);
3001
3002 if (renderbuffer != 0)
3003 {
3004 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003005
3006 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003007 renderbufferObject);
3008 }
3009 else
3010 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003011 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003012 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003013
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003014 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003015}
3016
3017void Context::framebufferTextureLayer(GLenum target,
3018 GLenum attachment,
3019 GLuint texture,
3020 GLint level,
3021 GLint layer)
3022{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003023 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003024 ASSERT(framebuffer);
3025
3026 if (texture != 0)
3027 {
3028 Texture *textureObject = getTexture(texture);
3029
3030 ImageIndex index = ImageIndex::MakeInvalid();
3031
3032 if (textureObject->getTarget() == GL_TEXTURE_3D)
3033 {
3034 index = ImageIndex::Make3D(level, layer);
3035 }
3036 else
3037 {
3038 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3039 index = ImageIndex::Make2DArray(level, layer);
3040 }
3041
Jamie Madilla02315b2017-02-23 14:14:47 -05003042 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003043 }
3044 else
3045 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003046 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003047 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003048
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003049 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003050}
3051
Martin Radev137032d2017-07-13 10:11:12 +03003052void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3053 GLenum attachment,
3054 GLuint texture,
3055 GLint level,
3056 GLint baseViewIndex,
3057 GLsizei numViews)
3058{
Martin Radev82ef7742017-08-08 17:44:58 +03003059 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3060 ASSERT(framebuffer);
3061
3062 if (texture != 0)
3063 {
3064 Texture *textureObj = getTexture(texture);
3065
Martin Radev18b75ba2017-08-15 15:50:40 +03003066 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003067 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3068 numViews, baseViewIndex);
3069 }
3070 else
3071 {
3072 framebuffer->resetAttachment(this, attachment);
3073 }
3074
3075 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003076}
3077
3078void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3079 GLenum attachment,
3080 GLuint texture,
3081 GLint level,
3082 GLsizei numViews,
3083 const GLint *viewportOffsets)
3084{
Martin Radev5dae57b2017-07-14 16:15:55 +03003085 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3086 ASSERT(framebuffer);
3087
3088 if (texture != 0)
3089 {
3090 Texture *textureObj = getTexture(texture);
3091
3092 ImageIndex index = ImageIndex::Make2D(level);
3093 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3094 textureObj, numViews, viewportOffsets);
3095 }
3096 else
3097 {
3098 framebuffer->resetAttachment(this, attachment);
3099 }
3100
3101 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003102}
3103
Jamie Madillc29968b2016-01-20 11:17:23 -05003104void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3105{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003106 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003107 ASSERT(framebuffer);
3108 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003109 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003110}
3111
3112void Context::readBuffer(GLenum mode)
3113{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003114 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003115 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003116 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003117}
3118
3119void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3120{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003121 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003122 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003123
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003124 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003125 ASSERT(framebuffer);
3126
3127 // The specification isn't clear what should be done when the framebuffer isn't complete.
3128 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003129 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003130}
3131
3132void Context::invalidateFramebuffer(GLenum target,
3133 GLsizei numAttachments,
3134 const GLenum *attachments)
3135{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003136 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003137 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003138
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003139 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003140 ASSERT(framebuffer);
3141
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003142 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003143 {
Jamie Madill437fa652016-05-03 15:13:24 -04003144 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003145 }
Jamie Madill437fa652016-05-03 15:13:24 -04003146
Jamie Madill4928b7c2017-06-20 12:57:39 -04003147 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003148}
3149
3150void Context::invalidateSubFramebuffer(GLenum target,
3151 GLsizei numAttachments,
3152 const GLenum *attachments,
3153 GLint x,
3154 GLint y,
3155 GLsizei width,
3156 GLsizei height)
3157{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003158 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003159 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003160
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003161 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003162 ASSERT(framebuffer);
3163
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003164 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003165 {
Jamie Madill437fa652016-05-03 15:13:24 -04003166 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003167 }
Jamie Madill437fa652016-05-03 15:13:24 -04003168
3169 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003170 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003171}
3172
Jamie Madill73a84962016-02-12 09:27:23 -05003173void Context::texImage2D(GLenum target,
3174 GLint level,
3175 GLint internalformat,
3176 GLsizei width,
3177 GLsizei height,
3178 GLint border,
3179 GLenum format,
3180 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003181 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003182{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003183 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003184
3185 Extents size(width, height, 1);
3186 Texture *texture =
3187 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003188 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3189 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003190}
3191
3192void Context::texImage3D(GLenum target,
3193 GLint level,
3194 GLint internalformat,
3195 GLsizei width,
3196 GLsizei height,
3197 GLsizei depth,
3198 GLint border,
3199 GLenum format,
3200 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003201 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003202{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003203 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003204
3205 Extents size(width, height, depth);
3206 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003207 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3208 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003209}
3210
3211void Context::texSubImage2D(GLenum target,
3212 GLint level,
3213 GLint xoffset,
3214 GLint yoffset,
3215 GLsizei width,
3216 GLsizei height,
3217 GLenum format,
3218 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003219 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003220{
3221 // Zero sized uploads are valid but no-ops
3222 if (width == 0 || height == 0)
3223 {
3224 return;
3225 }
3226
Jamie Madillad9f24e2016-02-12 09:27:24 -05003227 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003228
3229 Box area(xoffset, yoffset, 0, width, height, 1);
3230 Texture *texture =
3231 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003232 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3233 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003234}
3235
3236void Context::texSubImage3D(GLenum target,
3237 GLint level,
3238 GLint xoffset,
3239 GLint yoffset,
3240 GLint zoffset,
3241 GLsizei width,
3242 GLsizei height,
3243 GLsizei depth,
3244 GLenum format,
3245 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003246 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003247{
3248 // Zero sized uploads are valid but no-ops
3249 if (width == 0 || height == 0 || depth == 0)
3250 {
3251 return;
3252 }
3253
Jamie Madillad9f24e2016-02-12 09:27:24 -05003254 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003255
3256 Box area(xoffset, yoffset, zoffset, width, height, depth);
3257 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003258 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3259 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003260}
3261
3262void Context::compressedTexImage2D(GLenum target,
3263 GLint level,
3264 GLenum internalformat,
3265 GLsizei width,
3266 GLsizei height,
3267 GLint border,
3268 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003269 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003270{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003271 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003272
3273 Extents size(width, height, 1);
3274 Texture *texture =
3275 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003276 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003277 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003278 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003279}
3280
3281void Context::compressedTexImage3D(GLenum target,
3282 GLint level,
3283 GLenum internalformat,
3284 GLsizei width,
3285 GLsizei height,
3286 GLsizei depth,
3287 GLint border,
3288 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003289 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003290{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003291 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003292
3293 Extents size(width, height, depth);
3294 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003295 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003297 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003298}
3299
3300void Context::compressedTexSubImage2D(GLenum target,
3301 GLint level,
3302 GLint xoffset,
3303 GLint yoffset,
3304 GLsizei width,
3305 GLsizei height,
3306 GLenum format,
3307 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003308 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003309{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003310 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003311
3312 Box area(xoffset, yoffset, 0, width, height, 1);
3313 Texture *texture =
3314 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003315 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003316 format, imageSize,
3317 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003318}
3319
3320void Context::compressedTexSubImage3D(GLenum target,
3321 GLint level,
3322 GLint xoffset,
3323 GLint yoffset,
3324 GLint zoffset,
3325 GLsizei width,
3326 GLsizei height,
3327 GLsizei depth,
3328 GLenum format,
3329 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003330 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003331{
3332 // Zero sized uploads are valid but no-ops
3333 if (width == 0 || height == 0)
3334 {
3335 return;
3336 }
3337
Jamie Madillad9f24e2016-02-12 09:27:24 -05003338 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003339
3340 Box area(xoffset, yoffset, zoffset, width, height, depth);
3341 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003342 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003343 format, imageSize,
3344 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003345}
3346
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003347void Context::generateMipmap(GLenum target)
3348{
3349 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003350 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003351}
3352
Geoff Lang97073d12016-04-20 10:42:34 -07003353void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003354 GLint sourceLevel,
3355 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003356 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003357 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003358 GLint internalFormat,
3359 GLenum destType,
3360 GLboolean unpackFlipY,
3361 GLboolean unpackPremultiplyAlpha,
3362 GLboolean unpackUnmultiplyAlpha)
3363{
3364 syncStateForTexImage();
3365
3366 gl::Texture *sourceTexture = getTexture(sourceId);
3367 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003368 handleError(destTexture->copyTexture(
3369 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3370 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003371}
3372
3373void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003374 GLint sourceLevel,
3375 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003376 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003377 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003378 GLint xoffset,
3379 GLint yoffset,
3380 GLint x,
3381 GLint y,
3382 GLsizei width,
3383 GLsizei height,
3384 GLboolean unpackFlipY,
3385 GLboolean unpackPremultiplyAlpha,
3386 GLboolean unpackUnmultiplyAlpha)
3387{
3388 // Zero sized copies are valid but no-ops
3389 if (width == 0 || height == 0)
3390 {
3391 return;
3392 }
3393
3394 syncStateForTexImage();
3395
3396 gl::Texture *sourceTexture = getTexture(sourceId);
3397 gl::Texture *destTexture = getTexture(destId);
3398 Offset offset(xoffset, yoffset, 0);
3399 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003400 handleError(destTexture->copySubTexture(
3401 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3402 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003403}
3404
Geoff Lang47110bf2016-04-20 11:13:22 -07003405void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3406{
3407 syncStateForTexImage();
3408
3409 gl::Texture *sourceTexture = getTexture(sourceId);
3410 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003411 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003412}
3413
Geoff Lang496c02d2016-10-20 11:38:11 -07003414void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003415{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003416 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003417 ASSERT(buffer);
3418
Geoff Lang496c02d2016-10-20 11:38:11 -07003419 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003420}
3421
Jamie Madill876429b2017-04-20 15:46:24 -04003422void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003423{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003425 ASSERT(buffer);
3426
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003427 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003428 if (error.isError())
3429 {
Jamie Madill437fa652016-05-03 15:13:24 -04003430 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003431 return nullptr;
3432 }
3433
3434 return buffer->getMapPointer();
3435}
3436
3437GLboolean Context::unmapBuffer(GLenum target)
3438{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003439 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003440 ASSERT(buffer);
3441
3442 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003443 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003444 if (error.isError())
3445 {
Jamie Madill437fa652016-05-03 15:13:24 -04003446 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003447 return GL_FALSE;
3448 }
3449
3450 return result;
3451}
3452
Jamie Madill876429b2017-04-20 15:46:24 -04003453void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003454{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003455 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003456 ASSERT(buffer);
3457
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003458 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003459 if (error.isError())
3460 {
Jamie Madill437fa652016-05-03 15:13:24 -04003461 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003462 return nullptr;
3463 }
3464
3465 return buffer->getMapPointer();
3466}
3467
3468void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3469{
3470 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3471}
3472
Jamie Madillad9f24e2016-02-12 09:27:24 -05003473void Context::syncStateForReadPixels()
3474{
3475 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3476}
3477
3478void Context::syncStateForTexImage()
3479{
3480 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3481}
3482
3483void Context::syncStateForClear()
3484{
3485 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3486}
3487
3488void Context::syncStateForBlit()
3489{
3490 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3491}
3492
Jamie Madillc20ab272016-06-09 07:20:46 -07003493void Context::activeTexture(GLenum texture)
3494{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003495 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003496}
3497
Jamie Madill876429b2017-04-20 15:46:24 -04003498void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003499{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003500 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003501}
3502
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003503void Context::blendEquation(GLenum mode)
3504{
3505 mGLState.setBlendEquation(mode, mode);
3506}
3507
Jamie Madillc20ab272016-06-09 07:20:46 -07003508void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3509{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003511}
3512
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003513void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3514{
3515 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3516}
3517
Jamie Madillc20ab272016-06-09 07:20:46 -07003518void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3519{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
Jamie Madill876429b2017-04-20 15:46:24 -04003523void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003524{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
Jamie Madill876429b2017-04-20 15:46:24 -04003528void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003529{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003530 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003531}
3532
3533void Context::clearStencil(GLint s)
3534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003535 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003536}
3537
3538void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3539{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003540 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003541}
3542
3543void Context::cullFace(GLenum mode)
3544{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003545 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003546}
3547
3548void Context::depthFunc(GLenum func)
3549{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003551}
3552
3553void Context::depthMask(GLboolean flag)
3554{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003555 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003556}
3557
Jamie Madill876429b2017-04-20 15:46:24 -04003558void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003559{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003560 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003561}
3562
3563void Context::disable(GLenum cap)
3564{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003565 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003566}
3567
3568void Context::disableVertexAttribArray(GLuint index)
3569{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003570 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003571}
3572
3573void Context::enable(GLenum cap)
3574{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003575 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003576}
3577
3578void Context::enableVertexAttribArray(GLuint index)
3579{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003580 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003581}
3582
3583void Context::frontFace(GLenum mode)
3584{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003585 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003586}
3587
3588void Context::hint(GLenum target, GLenum mode)
3589{
3590 switch (target)
3591 {
3592 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003593 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003594 break;
3595
3596 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003597 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003598 break;
3599
3600 default:
3601 UNREACHABLE();
3602 return;
3603 }
3604}
3605
3606void Context::lineWidth(GLfloat width)
3607{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003608 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003609}
3610
3611void Context::pixelStorei(GLenum pname, GLint param)
3612{
3613 switch (pname)
3614 {
3615 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003616 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003617 break;
3618
3619 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003620 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003621 break;
3622
3623 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003624 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003625 break;
3626
3627 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003628 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003629 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003630 break;
3631
3632 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003633 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003634 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003635 break;
3636
3637 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003638 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003639 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003640 break;
3641
3642 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003643 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003644 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003645 break;
3646
3647 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003648 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003649 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003650 break;
3651
3652 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003653 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003654 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003655 break;
3656
3657 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003658 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003659 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003660 break;
3661
3662 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003663 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003664 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003665 break;
3666
3667 default:
3668 UNREACHABLE();
3669 return;
3670 }
3671}
3672
3673void Context::polygonOffset(GLfloat factor, GLfloat units)
3674{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003675 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003676}
3677
Jamie Madill876429b2017-04-20 15:46:24 -04003678void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003679{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003680 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003681}
3682
3683void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3684{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003685 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003686}
3687
3688void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3689{
3690 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3691 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003692 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003693 }
3694
3695 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3696 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003697 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003698 }
3699}
3700
3701void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3702{
3703 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3704 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003705 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003706 }
3707
3708 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3709 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003710 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003711 }
3712}
3713
3714void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3715{
3716 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3717 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003718 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003719 }
3720
3721 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3722 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003723 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003724 }
3725}
3726
3727void Context::vertexAttrib1f(GLuint index, GLfloat x)
3728{
3729 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003730 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003731}
3732
3733void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3734{
3735 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003736 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003737}
3738
3739void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3740{
3741 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003742 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003743}
3744
3745void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3746{
3747 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003748 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003749}
3750
3751void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3752{
3753 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003754 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003755}
3756
3757void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3758{
3759 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003760 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003761}
3762
3763void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3764{
3765 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003766 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003767}
3768
3769void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3770{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003771 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003772}
3773
3774void Context::vertexAttribPointer(GLuint index,
3775 GLint size,
3776 GLenum type,
3777 GLboolean normalized,
3778 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003779 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003780{
Shaodde78e82017-05-22 14:13:27 +08003781 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3782 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003783}
3784
Shao80957d92017-02-20 21:25:59 +08003785void Context::vertexAttribFormat(GLuint attribIndex,
3786 GLint size,
3787 GLenum type,
3788 GLboolean normalized,
3789 GLuint relativeOffset)
3790{
3791 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3792 relativeOffset);
3793}
3794
3795void Context::vertexAttribIFormat(GLuint attribIndex,
3796 GLint size,
3797 GLenum type,
3798 GLuint relativeOffset)
3799{
3800 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3801}
3802
3803void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3804{
Shaodde78e82017-05-22 14:13:27 +08003805 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003806}
3807
3808void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3809{
3810 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3811}
3812
Jamie Madillc20ab272016-06-09 07:20:46 -07003813void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3814{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003815 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003816}
3817
3818void Context::vertexAttribIPointer(GLuint index,
3819 GLint size,
3820 GLenum type,
3821 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003822 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003823{
Shaodde78e82017-05-22 14:13:27 +08003824 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3825 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003826}
3827
3828void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3829{
3830 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003831 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003832}
3833
3834void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3835{
3836 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003837 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003838}
3839
3840void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3841{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003842 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003843}
3844
3845void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3846{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003847 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003848}
3849
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003850void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3851{
3852 const VertexAttribCurrentValueData &currentValues =
3853 getGLState().getVertexAttribCurrentValue(index);
3854 const VertexArray *vao = getGLState().getVertexArray();
3855 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3856 currentValues, pname, params);
3857}
3858
3859void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3860{
3861 const VertexAttribCurrentValueData &currentValues =
3862 getGLState().getVertexAttribCurrentValue(index);
3863 const VertexArray *vao = getGLState().getVertexArray();
3864 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3865 currentValues, pname, params);
3866}
3867
3868void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3869{
3870 const VertexAttribCurrentValueData &currentValues =
3871 getGLState().getVertexAttribCurrentValue(index);
3872 const VertexArray *vao = getGLState().getVertexArray();
3873 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3874 currentValues, pname, params);
3875}
3876
3877void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3878{
3879 const VertexAttribCurrentValueData &currentValues =
3880 getGLState().getVertexAttribCurrentValue(index);
3881 const VertexArray *vao = getGLState().getVertexArray();
3882 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3883 currentValues, pname, params);
3884}
3885
Jamie Madill876429b2017-04-20 15:46:24 -04003886void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003887{
3888 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3889 QueryVertexAttribPointerv(attrib, pname, pointer);
3890}
3891
Jamie Madillc20ab272016-06-09 07:20:46 -07003892void Context::debugMessageControl(GLenum source,
3893 GLenum type,
3894 GLenum severity,
3895 GLsizei count,
3896 const GLuint *ids,
3897 GLboolean enabled)
3898{
3899 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003900 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3901 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003902}
3903
3904void Context::debugMessageInsert(GLenum source,
3905 GLenum type,
3906 GLuint id,
3907 GLenum severity,
3908 GLsizei length,
3909 const GLchar *buf)
3910{
3911 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003912 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003913}
3914
3915void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3916{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003917 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003918}
3919
3920GLuint Context::getDebugMessageLog(GLuint count,
3921 GLsizei bufSize,
3922 GLenum *sources,
3923 GLenum *types,
3924 GLuint *ids,
3925 GLenum *severities,
3926 GLsizei *lengths,
3927 GLchar *messageLog)
3928{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003929 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3930 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003931}
3932
3933void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3934{
3935 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003936 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003937}
3938
3939void Context::popDebugGroup()
3940{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003941 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003942}
3943
Jamie Madill876429b2017-04-20 15:46:24 -04003944void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003945{
3946 Buffer *buffer = mGLState.getTargetBuffer(target);
3947 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003948 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003949}
3950
Jamie Madill876429b2017-04-20 15:46:24 -04003951void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003952{
3953 if (data == nullptr)
3954 {
3955 return;
3956 }
3957
3958 Buffer *buffer = mGLState.getTargetBuffer(target);
3959 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003960 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003961}
3962
Jamie Madillef300b12016-10-07 15:12:09 -04003963void Context::attachShader(GLuint program, GLuint shader)
3964{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003965 auto programObject = mState.mShaderPrograms->getProgram(program);
3966 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003967 ASSERT(programObject && shaderObject);
3968 programObject->attachShader(shaderObject);
3969}
3970
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003971const Workarounds &Context::getWorkarounds() const
3972{
3973 return mWorkarounds;
3974}
3975
Jamie Madillb0817d12016-11-01 15:48:31 -04003976void Context::copyBufferSubData(GLenum readTarget,
3977 GLenum writeTarget,
3978 GLintptr readOffset,
3979 GLintptr writeOffset,
3980 GLsizeiptr size)
3981{
3982 // if size is zero, the copy is a successful no-op
3983 if (size == 0)
3984 {
3985 return;
3986 }
3987
3988 // TODO(jmadill): cache these.
3989 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3990 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3991
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003992 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003993}
3994
Jamie Madill01a80ee2016-11-07 12:06:18 -05003995void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3996{
3997 Program *programObject = getProgram(program);
3998 // TODO(jmadill): Re-use this from the validation if possible.
3999 ASSERT(programObject);
4000 programObject->bindAttributeLocation(index, name);
4001}
4002
4003void Context::bindBuffer(GLenum target, GLuint buffer)
4004{
4005 switch (target)
4006 {
4007 case GL_ARRAY_BUFFER:
4008 bindArrayBuffer(buffer);
4009 break;
4010 case GL_ELEMENT_ARRAY_BUFFER:
4011 bindElementArrayBuffer(buffer);
4012 break;
4013 case GL_COPY_READ_BUFFER:
4014 bindCopyReadBuffer(buffer);
4015 break;
4016 case GL_COPY_WRITE_BUFFER:
4017 bindCopyWriteBuffer(buffer);
4018 break;
4019 case GL_PIXEL_PACK_BUFFER:
4020 bindPixelPackBuffer(buffer);
4021 break;
4022 case GL_PIXEL_UNPACK_BUFFER:
4023 bindPixelUnpackBuffer(buffer);
4024 break;
4025 case GL_UNIFORM_BUFFER:
4026 bindGenericUniformBuffer(buffer);
4027 break;
4028 case GL_TRANSFORM_FEEDBACK_BUFFER:
4029 bindGenericTransformFeedbackBuffer(buffer);
4030 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004031 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004032 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004033 break;
4034 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004035 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004036 break;
4037 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004038 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004039 break;
4040 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004041 if (buffer != 0)
4042 {
4043 // Binding buffers to this binding point is not implemented yet.
4044 UNIMPLEMENTED();
4045 }
Geoff Lang3b573612016-10-31 14:08:10 -04004046 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004047
4048 default:
4049 UNREACHABLE();
4050 break;
4051 }
4052}
4053
Jiajia Qin6eafb042016-12-27 17:04:07 +08004054void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4055{
4056 bindBufferRange(target, index, buffer, 0, 0);
4057}
4058
4059void Context::bindBufferRange(GLenum target,
4060 GLuint index,
4061 GLuint buffer,
4062 GLintptr offset,
4063 GLsizeiptr size)
4064{
4065 switch (target)
4066 {
4067 case GL_TRANSFORM_FEEDBACK_BUFFER:
4068 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4069 bindGenericTransformFeedbackBuffer(buffer);
4070 break;
4071 case GL_UNIFORM_BUFFER:
4072 bindIndexedUniformBuffer(buffer, index, offset, size);
4073 bindGenericUniformBuffer(buffer);
4074 break;
4075 case GL_ATOMIC_COUNTER_BUFFER:
4076 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4077 bindGenericAtomicCounterBuffer(buffer);
4078 break;
4079 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004080 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4081 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004082 break;
4083 default:
4084 UNREACHABLE();
4085 break;
4086 }
4087}
4088
Jamie Madill01a80ee2016-11-07 12:06:18 -05004089void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4090{
4091 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4092 {
4093 bindReadFramebuffer(framebuffer);
4094 }
4095
4096 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4097 {
4098 bindDrawFramebuffer(framebuffer);
4099 }
4100}
4101
4102void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4103{
4104 ASSERT(target == GL_RENDERBUFFER);
4105 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004106 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004107 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004108}
4109
JiangYizhoubddc46b2016-12-09 09:50:51 +08004110void Context::texStorage2DMultisample(GLenum target,
4111 GLsizei samples,
4112 GLenum internalformat,
4113 GLsizei width,
4114 GLsizei height,
4115 GLboolean fixedsamplelocations)
4116{
4117 Extents size(width, height, 1);
4118 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004119 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004120 fixedsamplelocations));
4121}
4122
4123void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4124{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004125 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004126 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4127
4128 switch (pname)
4129 {
4130 case GL_SAMPLE_POSITION:
4131 handleError(framebuffer->getSamplePosition(index, val));
4132 break;
4133 default:
4134 UNREACHABLE();
4135 }
4136}
4137
Jamie Madille8fb6402017-02-14 17:56:40 -05004138void Context::renderbufferStorage(GLenum target,
4139 GLenum internalformat,
4140 GLsizei width,
4141 GLsizei height)
4142{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004143 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4144 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4145
Jamie Madille8fb6402017-02-14 17:56:40 -05004146 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004147 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004148}
4149
4150void Context::renderbufferStorageMultisample(GLenum target,
4151 GLsizei samples,
4152 GLenum internalformat,
4153 GLsizei width,
4154 GLsizei height)
4155{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004156 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4157 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004158
4159 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004160 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004161 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004162}
4163
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004164void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4165{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004166 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004167 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004168}
4169
JiangYizhoue18e6392017-02-20 10:32:23 +08004170void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4171{
4172 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4173 QueryFramebufferParameteriv(framebuffer, pname, params);
4174}
4175
4176void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4177{
4178 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4179 SetFramebufferParameteri(framebuffer, pname, param);
4180}
4181
Jamie Madillb3f26b92017-07-19 15:07:41 -04004182Error Context::getScratchBuffer(size_t requstedSizeBytes,
4183 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004184{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004185 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4186 {
4187 return OutOfMemory() << "Failed to allocate internal buffer.";
4188 }
4189 return NoError();
4190}
4191
4192Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4193 angle::MemoryBuffer **zeroBufferOut) const
4194{
4195 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004196 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004197 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004198 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004199 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004200}
4201
Xinghua Cao2b396592017-03-29 15:36:04 +08004202void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4203{
4204 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4205 {
4206 return;
4207 }
4208
Jamie Madillfe548342017-06-19 11:13:24 -04004209 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004210}
4211
JiangYizhou165361c2017-06-07 14:56:57 +08004212void Context::texStorage2D(GLenum target,
4213 GLsizei levels,
4214 GLenum internalFormat,
4215 GLsizei width,
4216 GLsizei height)
4217{
4218 Extents size(width, height, 1);
4219 Texture *texture = getTargetTexture(target);
4220 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4221}
4222
4223void Context::texStorage3D(GLenum target,
4224 GLsizei levels,
4225 GLenum internalFormat,
4226 GLsizei width,
4227 GLsizei height,
4228 GLsizei depth)
4229{
4230 Extents size(width, height, depth);
4231 Texture *texture = getTargetTexture(target);
4232 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4233}
4234
Jamie Madillc1d770e2017-04-13 17:31:24 -04004235GLenum Context::checkFramebufferStatus(GLenum target)
4236{
4237 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4238 ASSERT(framebuffer);
4239
4240 return framebuffer->checkStatus(this);
4241}
4242
4243void Context::compileShader(GLuint shader)
4244{
4245 Shader *shaderObject = GetValidShader(this, shader);
4246 if (!shaderObject)
4247 {
4248 return;
4249 }
4250 shaderObject->compile(this);
4251}
4252
4253void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4254{
4255 for (int i = 0; i < n; i++)
4256 {
4257 deleteBuffer(buffers[i]);
4258 }
4259}
4260
4261void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4262{
4263 for (int i = 0; i < n; i++)
4264 {
4265 if (framebuffers[i] != 0)
4266 {
4267 deleteFramebuffer(framebuffers[i]);
4268 }
4269 }
4270}
4271
4272void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4273{
4274 for (int i = 0; i < n; i++)
4275 {
4276 deleteRenderbuffer(renderbuffers[i]);
4277 }
4278}
4279
4280void Context::deleteTextures(GLsizei n, const GLuint *textures)
4281{
4282 for (int i = 0; i < n; i++)
4283 {
4284 if (textures[i] != 0)
4285 {
4286 deleteTexture(textures[i]);
4287 }
4288 }
4289}
4290
4291void Context::detachShader(GLuint program, GLuint shader)
4292{
4293 Program *programObject = getProgram(program);
4294 ASSERT(programObject);
4295
4296 Shader *shaderObject = getShader(shader);
4297 ASSERT(shaderObject);
4298
4299 programObject->detachShader(this, shaderObject);
4300}
4301
4302void Context::genBuffers(GLsizei n, GLuint *buffers)
4303{
4304 for (int i = 0; i < n; i++)
4305 {
4306 buffers[i] = createBuffer();
4307 }
4308}
4309
4310void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4311{
4312 for (int i = 0; i < n; i++)
4313 {
4314 framebuffers[i] = createFramebuffer();
4315 }
4316}
4317
4318void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4319{
4320 for (int i = 0; i < n; i++)
4321 {
4322 renderbuffers[i] = createRenderbuffer();
4323 }
4324}
4325
4326void Context::genTextures(GLsizei n, GLuint *textures)
4327{
4328 for (int i = 0; i < n; i++)
4329 {
4330 textures[i] = createTexture();
4331 }
4332}
4333
4334void Context::getActiveAttrib(GLuint program,
4335 GLuint index,
4336 GLsizei bufsize,
4337 GLsizei *length,
4338 GLint *size,
4339 GLenum *type,
4340 GLchar *name)
4341{
4342 Program *programObject = getProgram(program);
4343 ASSERT(programObject);
4344 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4345}
4346
4347void Context::getActiveUniform(GLuint program,
4348 GLuint index,
4349 GLsizei bufsize,
4350 GLsizei *length,
4351 GLint *size,
4352 GLenum *type,
4353 GLchar *name)
4354{
4355 Program *programObject = getProgram(program);
4356 ASSERT(programObject);
4357 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4358}
4359
4360void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4361{
4362 Program *programObject = getProgram(program);
4363 ASSERT(programObject);
4364 programObject->getAttachedShaders(maxcount, count, shaders);
4365}
4366
4367GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4368{
4369 Program *programObject = getProgram(program);
4370 ASSERT(programObject);
4371 return programObject->getAttributeLocation(name);
4372}
4373
4374void Context::getBooleanv(GLenum pname, GLboolean *params)
4375{
4376 GLenum nativeType;
4377 unsigned int numParams = 0;
4378 getQueryParameterInfo(pname, &nativeType, &numParams);
4379
4380 if (nativeType == GL_BOOL)
4381 {
4382 getBooleanvImpl(pname, params);
4383 }
4384 else
4385 {
4386 CastStateValues(this, nativeType, pname, numParams, params);
4387 }
4388}
4389
4390void Context::getFloatv(GLenum pname, GLfloat *params)
4391{
4392 GLenum nativeType;
4393 unsigned int numParams = 0;
4394 getQueryParameterInfo(pname, &nativeType, &numParams);
4395
4396 if (nativeType == GL_FLOAT)
4397 {
4398 getFloatvImpl(pname, params);
4399 }
4400 else
4401 {
4402 CastStateValues(this, nativeType, pname, numParams, params);
4403 }
4404}
4405
4406void Context::getIntegerv(GLenum pname, GLint *params)
4407{
4408 GLenum nativeType;
4409 unsigned int numParams = 0;
4410 getQueryParameterInfo(pname, &nativeType, &numParams);
4411
4412 if (nativeType == GL_INT)
4413 {
4414 getIntegervImpl(pname, params);
4415 }
4416 else
4417 {
4418 CastStateValues(this, nativeType, pname, numParams, params);
4419 }
4420}
4421
4422void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4423{
4424 Program *programObject = getProgram(program);
4425 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004426 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004427}
4428
Jamie Madillbe849e42017-05-02 15:49:00 -04004429void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004430{
4431 Program *programObject = getProgram(program);
4432 ASSERT(programObject);
4433 programObject->getInfoLog(bufsize, length, infolog);
4434}
4435
4436void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4437{
4438 Shader *shaderObject = getShader(shader);
4439 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004440 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004441}
4442
4443void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4444{
4445 Shader *shaderObject = getShader(shader);
4446 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004447 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004448}
4449
4450void Context::getShaderPrecisionFormat(GLenum shadertype,
4451 GLenum precisiontype,
4452 GLint *range,
4453 GLint *precision)
4454{
4455 // TODO(jmadill): Compute shaders.
4456
4457 switch (shadertype)
4458 {
4459 case GL_VERTEX_SHADER:
4460 switch (precisiontype)
4461 {
4462 case GL_LOW_FLOAT:
4463 mCaps.vertexLowpFloat.get(range, precision);
4464 break;
4465 case GL_MEDIUM_FLOAT:
4466 mCaps.vertexMediumpFloat.get(range, precision);
4467 break;
4468 case GL_HIGH_FLOAT:
4469 mCaps.vertexHighpFloat.get(range, precision);
4470 break;
4471
4472 case GL_LOW_INT:
4473 mCaps.vertexLowpInt.get(range, precision);
4474 break;
4475 case GL_MEDIUM_INT:
4476 mCaps.vertexMediumpInt.get(range, precision);
4477 break;
4478 case GL_HIGH_INT:
4479 mCaps.vertexHighpInt.get(range, precision);
4480 break;
4481
4482 default:
4483 UNREACHABLE();
4484 return;
4485 }
4486 break;
4487
4488 case GL_FRAGMENT_SHADER:
4489 switch (precisiontype)
4490 {
4491 case GL_LOW_FLOAT:
4492 mCaps.fragmentLowpFloat.get(range, precision);
4493 break;
4494 case GL_MEDIUM_FLOAT:
4495 mCaps.fragmentMediumpFloat.get(range, precision);
4496 break;
4497 case GL_HIGH_FLOAT:
4498 mCaps.fragmentHighpFloat.get(range, precision);
4499 break;
4500
4501 case GL_LOW_INT:
4502 mCaps.fragmentLowpInt.get(range, precision);
4503 break;
4504 case GL_MEDIUM_INT:
4505 mCaps.fragmentMediumpInt.get(range, precision);
4506 break;
4507 case GL_HIGH_INT:
4508 mCaps.fragmentHighpInt.get(range, precision);
4509 break;
4510
4511 default:
4512 UNREACHABLE();
4513 return;
4514 }
4515 break;
4516
4517 default:
4518 UNREACHABLE();
4519 return;
4520 }
4521}
4522
4523void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4524{
4525 Shader *shaderObject = getShader(shader);
4526 ASSERT(shaderObject);
4527 shaderObject->getSource(bufsize, length, source);
4528}
4529
4530void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4531{
4532 Program *programObject = getProgram(program);
4533 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004534 programObject->getUniformfv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004535}
4536
4537void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4538{
4539 Program *programObject = getProgram(program);
4540 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004541 programObject->getUniformiv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004542}
4543
4544GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4545{
4546 Program *programObject = getProgram(program);
4547 ASSERT(programObject);
4548 return programObject->getUniformLocation(name);
4549}
4550
4551GLboolean Context::isBuffer(GLuint buffer)
4552{
4553 if (buffer == 0)
4554 {
4555 return GL_FALSE;
4556 }
4557
4558 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4559}
4560
4561GLboolean Context::isEnabled(GLenum cap)
4562{
4563 return mGLState.getEnableFeature(cap);
4564}
4565
4566GLboolean Context::isFramebuffer(GLuint framebuffer)
4567{
4568 if (framebuffer == 0)
4569 {
4570 return GL_FALSE;
4571 }
4572
4573 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4574}
4575
4576GLboolean Context::isProgram(GLuint program)
4577{
4578 if (program == 0)
4579 {
4580 return GL_FALSE;
4581 }
4582
4583 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4584}
4585
4586GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4587{
4588 if (renderbuffer == 0)
4589 {
4590 return GL_FALSE;
4591 }
4592
4593 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4594}
4595
4596GLboolean Context::isShader(GLuint shader)
4597{
4598 if (shader == 0)
4599 {
4600 return GL_FALSE;
4601 }
4602
4603 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4604}
4605
4606GLboolean Context::isTexture(GLuint texture)
4607{
4608 if (texture == 0)
4609 {
4610 return GL_FALSE;
4611 }
4612
4613 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4614}
4615
4616void Context::linkProgram(GLuint program)
4617{
4618 Program *programObject = getProgram(program);
4619 ASSERT(programObject);
4620 handleError(programObject->link(this));
Martin Radev0abb7a22017-08-28 15:34:45 +03004621 mGLState.onProgramExecutableChange(programObject);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004622}
4623
4624void Context::releaseShaderCompiler()
4625{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004626 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004627}
4628
4629void Context::shaderBinary(GLsizei n,
4630 const GLuint *shaders,
4631 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004632 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004633 GLsizei length)
4634{
4635 // No binary shader formats are supported.
4636 UNIMPLEMENTED();
4637}
4638
4639void Context::shaderSource(GLuint shader,
4640 GLsizei count,
4641 const GLchar *const *string,
4642 const GLint *length)
4643{
4644 Shader *shaderObject = getShader(shader);
4645 ASSERT(shaderObject);
4646 shaderObject->setSource(count, string, length);
4647}
4648
4649void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4650{
4651 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4652}
4653
4654void Context::stencilMask(GLuint mask)
4655{
4656 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4657}
4658
4659void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4660{
4661 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4662}
4663
4664void Context::uniform1f(GLint location, GLfloat x)
4665{
4666 Program *program = mGLState.getProgram();
4667 program->setUniform1fv(location, 1, &x);
4668}
4669
4670void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4671{
4672 Program *program = mGLState.getProgram();
4673 program->setUniform1fv(location, count, v);
4674}
4675
4676void Context::uniform1i(GLint location, GLint x)
4677{
4678 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004679 if (program->setUniform1iv(location, 1, &x) == Program::SetUniformResult::SamplerChanged)
4680 {
4681 mGLState.setObjectDirty(GL_PROGRAM);
4682 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004683}
4684
4685void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4686{
4687 Program *program = mGLState.getProgram();
Jamie Madill81c2e252017-09-09 23:32:46 -04004688 if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged)
4689 {
4690 mGLState.setObjectDirty(GL_PROGRAM);
4691 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004692}
4693
4694void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4695{
4696 GLfloat xy[2] = {x, y};
4697 Program *program = mGLState.getProgram();
4698 program->setUniform2fv(location, 1, xy);
4699}
4700
4701void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4702{
4703 Program *program = mGLState.getProgram();
4704 program->setUniform2fv(location, count, v);
4705}
4706
4707void Context::uniform2i(GLint location, GLint x, GLint y)
4708{
4709 GLint xy[2] = {x, y};
4710 Program *program = mGLState.getProgram();
4711 program->setUniform2iv(location, 1, xy);
4712}
4713
4714void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4715{
4716 Program *program = mGLState.getProgram();
4717 program->setUniform2iv(location, count, v);
4718}
4719
4720void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4721{
4722 GLfloat xyz[3] = {x, y, z};
4723 Program *program = mGLState.getProgram();
4724 program->setUniform3fv(location, 1, xyz);
4725}
4726
4727void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4728{
4729 Program *program = mGLState.getProgram();
4730 program->setUniform3fv(location, count, v);
4731}
4732
4733void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4734{
4735 GLint xyz[3] = {x, y, z};
4736 Program *program = mGLState.getProgram();
4737 program->setUniform3iv(location, 1, xyz);
4738}
4739
4740void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4741{
4742 Program *program = mGLState.getProgram();
4743 program->setUniform3iv(location, count, v);
4744}
4745
4746void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4747{
4748 GLfloat xyzw[4] = {x, y, z, w};
4749 Program *program = mGLState.getProgram();
4750 program->setUniform4fv(location, 1, xyzw);
4751}
4752
4753void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4754{
4755 Program *program = mGLState.getProgram();
4756 program->setUniform4fv(location, count, v);
4757}
4758
4759void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4760{
4761 GLint xyzw[4] = {x, y, z, w};
4762 Program *program = mGLState.getProgram();
4763 program->setUniform4iv(location, 1, xyzw);
4764}
4765
4766void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4767{
4768 Program *program = mGLState.getProgram();
4769 program->setUniform4iv(location, count, v);
4770}
4771
4772void Context::uniformMatrix2fv(GLint location,
4773 GLsizei count,
4774 GLboolean transpose,
4775 const GLfloat *value)
4776{
4777 Program *program = mGLState.getProgram();
4778 program->setUniformMatrix2fv(location, count, transpose, value);
4779}
4780
4781void Context::uniformMatrix3fv(GLint location,
4782 GLsizei count,
4783 GLboolean transpose,
4784 const GLfloat *value)
4785{
4786 Program *program = mGLState.getProgram();
4787 program->setUniformMatrix3fv(location, count, transpose, value);
4788}
4789
4790void Context::uniformMatrix4fv(GLint location,
4791 GLsizei count,
4792 GLboolean transpose,
4793 const GLfloat *value)
4794{
4795 Program *program = mGLState.getProgram();
4796 program->setUniformMatrix4fv(location, count, transpose, value);
4797}
4798
4799void Context::validateProgram(GLuint program)
4800{
4801 Program *programObject = getProgram(program);
4802 ASSERT(programObject);
4803 programObject->validate(mCaps);
4804}
4805
Jamie Madilld04908b2017-06-09 14:15:35 -04004806void Context::getProgramBinary(GLuint program,
4807 GLsizei bufSize,
4808 GLsizei *length,
4809 GLenum *binaryFormat,
4810 void *binary)
4811{
4812 Program *programObject = getProgram(program);
4813 ASSERT(programObject != nullptr);
4814
4815 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4816}
4817
4818void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4819{
4820 Program *programObject = getProgram(program);
4821 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004822
Jamie Madilld04908b2017-06-09 14:15:35 -04004823 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4824}
4825
Jamie Madillff325f12017-08-26 15:06:05 -04004826void Context::uniform1ui(GLint location, GLuint v0)
4827{
4828 Program *program = mGLState.getProgram();
4829 program->setUniform1uiv(location, 1, &v0);
4830}
4831
4832void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4833{
4834 Program *program = mGLState.getProgram();
4835 const GLuint xy[] = {v0, v1};
4836 program->setUniform2uiv(location, 1, xy);
4837}
4838
4839void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4840{
4841 Program *program = mGLState.getProgram();
4842 const GLuint xyz[] = {v0, v1, v2};
4843 program->setUniform3uiv(location, 1, xyz);
4844}
4845
4846void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4847{
4848 Program *program = mGLState.getProgram();
4849 const GLuint xyzw[] = {v0, v1, v2, v3};
4850 program->setUniform4uiv(location, 1, xyzw);
4851}
4852
4853void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4854{
4855 Program *program = mGLState.getProgram();
4856 program->setUniform1uiv(location, count, value);
4857}
4858void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4859{
4860 Program *program = mGLState.getProgram();
4861 program->setUniform2uiv(location, count, value);
4862}
4863
4864void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4865{
4866 Program *program = mGLState.getProgram();
4867 program->setUniform3uiv(location, count, value);
4868}
4869
4870void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4871{
4872 Program *program = mGLState.getProgram();
4873 program->setUniform4uiv(location, count, value);
4874}
4875
Jamie Madillf0e04492017-08-26 15:28:42 -04004876void Context::genQueries(GLsizei n, GLuint *ids)
4877{
4878 for (GLsizei i = 0; i < n; i++)
4879 {
4880 GLuint handle = mQueryHandleAllocator.allocate();
4881 mQueryMap.assign(handle, nullptr);
4882 ids[i] = handle;
4883 }
4884}
4885
4886void Context::deleteQueries(GLsizei n, const GLuint *ids)
4887{
4888 for (int i = 0; i < n; i++)
4889 {
4890 GLuint query = ids[i];
4891
4892 Query *queryObject = nullptr;
4893 if (mQueryMap.erase(query, &queryObject))
4894 {
4895 mQueryHandleAllocator.release(query);
4896 if (queryObject)
4897 {
4898 queryObject->release(this);
4899 }
4900 }
4901 }
4902}
4903
4904GLboolean Context::isQuery(GLuint id)
4905{
4906 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4907}
4908
Jamie Madillc8c95812017-08-26 18:40:09 -04004909void Context::uniformMatrix2x3fv(GLint location,
4910 GLsizei count,
4911 GLboolean transpose,
4912 const GLfloat *value)
4913{
4914 Program *program = mGLState.getProgram();
4915 program->setUniformMatrix2x3fv(location, count, transpose, value);
4916}
4917
4918void Context::uniformMatrix3x2fv(GLint location,
4919 GLsizei count,
4920 GLboolean transpose,
4921 const GLfloat *value)
4922{
4923 Program *program = mGLState.getProgram();
4924 program->setUniformMatrix3x2fv(location, count, transpose, value);
4925}
4926
4927void Context::uniformMatrix2x4fv(GLint location,
4928 GLsizei count,
4929 GLboolean transpose,
4930 const GLfloat *value)
4931{
4932 Program *program = mGLState.getProgram();
4933 program->setUniformMatrix2x4fv(location, count, transpose, value);
4934}
4935
4936void Context::uniformMatrix4x2fv(GLint location,
4937 GLsizei count,
4938 GLboolean transpose,
4939 const GLfloat *value)
4940{
4941 Program *program = mGLState.getProgram();
4942 program->setUniformMatrix4x2fv(location, count, transpose, value);
4943}
4944
4945void Context::uniformMatrix3x4fv(GLint location,
4946 GLsizei count,
4947 GLboolean transpose,
4948 const GLfloat *value)
4949{
4950 Program *program = mGLState.getProgram();
4951 program->setUniformMatrix3x4fv(location, count, transpose, value);
4952}
4953
4954void Context::uniformMatrix4x3fv(GLint location,
4955 GLsizei count,
4956 GLboolean transpose,
4957 const GLfloat *value)
4958{
4959 Program *program = mGLState.getProgram();
4960 program->setUniformMatrix4x3fv(location, count, transpose, value);
4961}
4962
Jamie Madilld7576732017-08-26 18:49:50 -04004963void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
4964{
4965 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4966 {
4967 GLuint vertexArray = arrays[arrayIndex];
4968
4969 if (arrays[arrayIndex] != 0)
4970 {
4971 VertexArray *vertexArrayObject = nullptr;
4972 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
4973 {
4974 if (vertexArrayObject != nullptr)
4975 {
4976 detachVertexArray(vertexArray);
4977 vertexArrayObject->onDestroy(this);
4978 }
4979
4980 mVertexArrayHandleAllocator.release(vertexArray);
4981 }
4982 }
4983 }
4984}
4985
4986void Context::genVertexArrays(GLsizei n, GLuint *arrays)
4987{
4988 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4989 {
4990 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
4991 mVertexArrayMap.assign(vertexArray, nullptr);
4992 arrays[arrayIndex] = vertexArray;
4993 }
4994}
4995
4996bool Context::isVertexArray(GLuint array)
4997{
4998 if (array == 0)
4999 {
5000 return GL_FALSE;
5001 }
5002
5003 VertexArray *vao = getVertexArray(array);
5004 return (vao != nullptr ? GL_TRUE : GL_FALSE);
5005}
5006
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04005007void Context::endTransformFeedback()
5008{
5009 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5010 transformFeedback->end(this);
5011}
5012
5013void Context::transformFeedbackVaryings(GLuint program,
5014 GLsizei count,
5015 const GLchar *const *varyings,
5016 GLenum bufferMode)
5017{
5018 Program *programObject = getProgram(program);
5019 ASSERT(programObject);
5020 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
5021}
5022
5023void Context::getTransformFeedbackVarying(GLuint program,
5024 GLuint index,
5025 GLsizei bufSize,
5026 GLsizei *length,
5027 GLsizei *size,
5028 GLenum *type,
5029 GLchar *name)
5030{
5031 Program *programObject = getProgram(program);
5032 ASSERT(programObject);
5033 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5034}
5035
5036void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5037{
5038 for (int i = 0; i < n; i++)
5039 {
5040 GLuint transformFeedback = ids[i];
5041 if (transformFeedback == 0)
5042 {
5043 continue;
5044 }
5045
5046 TransformFeedback *transformFeedbackObject = nullptr;
5047 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5048 {
5049 if (transformFeedbackObject != nullptr)
5050 {
5051 detachTransformFeedback(transformFeedback);
5052 transformFeedbackObject->release(this);
5053 }
5054
5055 mTransformFeedbackHandleAllocator.release(transformFeedback);
5056 }
5057 }
5058}
5059
5060void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5061{
5062 for (int i = 0; i < n; i++)
5063 {
5064 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5065 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5066 ids[i] = transformFeedback;
5067 }
5068}
5069
5070bool Context::isTransformFeedback(GLuint id)
5071{
5072 if (id == 0)
5073 {
5074 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5075 // returns FALSE
5076 return GL_FALSE;
5077 }
5078
5079 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5080 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5081}
5082
5083void Context::pauseTransformFeedback()
5084{
5085 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5086 transformFeedback->pause();
5087}
5088
5089void Context::resumeTransformFeedback()
5090{
5091 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5092 transformFeedback->resume();
5093}
5094
Jamie Madill12e957f2017-08-26 21:42:26 -04005095void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5096{
5097 const Program *programObject = getProgram(program);
Jamie Madill54164b02017-08-28 15:17:37 -04005098 programObject->getUniformuiv(this, location, params);
Jamie Madill12e957f2017-08-26 21:42:26 -04005099}
5100
5101GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5102{
5103 const Program *programObject = getProgram(program);
5104 return programObject->getFragDataLocation(name);
5105}
5106
5107void Context::getUniformIndices(GLuint program,
5108 GLsizei uniformCount,
5109 const GLchar *const *uniformNames,
5110 GLuint *uniformIndices)
5111{
5112 const Program *programObject = getProgram(program);
5113 if (!programObject->isLinked())
5114 {
5115 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5116 {
5117 uniformIndices[uniformId] = GL_INVALID_INDEX;
5118 }
5119 }
5120 else
5121 {
5122 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5123 {
5124 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5125 }
5126 }
5127}
5128
5129void Context::getActiveUniformsiv(GLuint program,
5130 GLsizei uniformCount,
5131 const GLuint *uniformIndices,
5132 GLenum pname,
5133 GLint *params)
5134{
5135 const Program *programObject = getProgram(program);
5136 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5137 {
5138 const GLuint index = uniformIndices[uniformId];
5139 params[uniformId] = programObject->getActiveUniformi(index, pname);
5140 }
5141}
5142
5143GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5144{
5145 const Program *programObject = getProgram(program);
5146 return programObject->getUniformBlockIndex(uniformBlockName);
5147}
5148
5149void Context::getActiveUniformBlockiv(GLuint program,
5150 GLuint uniformBlockIndex,
5151 GLenum pname,
5152 GLint *params)
5153{
5154 const Program *programObject = getProgram(program);
5155 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5156}
5157
5158void Context::getActiveUniformBlockName(GLuint program,
5159 GLuint uniformBlockIndex,
5160 GLsizei bufSize,
5161 GLsizei *length,
5162 GLchar *uniformBlockName)
5163{
5164 const Program *programObject = getProgram(program);
5165 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5166}
5167
5168void Context::uniformBlockBinding(GLuint program,
5169 GLuint uniformBlockIndex,
5170 GLuint uniformBlockBinding)
5171{
5172 Program *programObject = getProgram(program);
5173 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5174}
5175
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005176GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5177{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005178 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5179 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005180
Jamie Madill70b5bb02017-08-28 13:32:37 -04005181 Sync *syncObject = getSync(syncHandle);
5182 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005183 if (error.isError())
5184 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005185 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005186 handleError(error);
5187 return nullptr;
5188 }
5189
Jamie Madill70b5bb02017-08-28 13:32:37 -04005190 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005191}
5192
5193GLboolean Context::isSync(GLsync sync)
5194{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005195 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005196}
5197
5198GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5199{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005200 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005201
5202 GLenum result = GL_WAIT_FAILED;
5203 handleError(syncObject->clientWait(flags, timeout, &result));
5204 return result;
5205}
5206
5207void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5208{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005209 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005210 handleError(syncObject->serverWait(flags, timeout));
5211}
5212
5213void Context::getInteger64v(GLenum pname, GLint64 *params)
5214{
5215 GLenum nativeType = GL_NONE;
5216 unsigned int numParams = 0;
5217 getQueryParameterInfo(pname, &nativeType, &numParams);
5218
5219 if (nativeType == GL_INT_64_ANGLEX)
5220 {
5221 getInteger64vImpl(pname, params);
5222 }
5223 else
5224 {
5225 CastStateValues(this, nativeType, pname, numParams, params);
5226 }
5227}
5228
Jamie Madill3ef140a2017-08-26 23:11:21 -04005229void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5230{
5231 Buffer *buffer = mGLState.getTargetBuffer(target);
5232 QueryBufferParameteri64v(buffer, pname, params);
5233}
5234
5235void Context::genSamplers(GLsizei count, GLuint *samplers)
5236{
5237 for (int i = 0; i < count; i++)
5238 {
5239 samplers[i] = mState.mSamplers->createSampler();
5240 }
5241}
5242
5243void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5244{
5245 for (int i = 0; i < count; i++)
5246 {
5247 GLuint sampler = samplers[i];
5248
5249 if (mState.mSamplers->getSampler(sampler))
5250 {
5251 detachSampler(sampler);
5252 }
5253
5254 mState.mSamplers->deleteObject(this, sampler);
5255 }
5256}
5257
5258void Context::getInternalformativ(GLenum target,
5259 GLenum internalformat,
5260 GLenum pname,
5261 GLsizei bufSize,
5262 GLint *params)
5263{
5264 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5265 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5266}
5267
Jamie Madill81c2e252017-09-09 23:32:46 -04005268void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
5269{
5270 Program *programObject = getProgram(program);
5271 ASSERT(programObject);
5272 if (programObject->setUniform1iv(location, count, value) ==
5273 Program::SetUniformResult::SamplerChanged)
5274 {
5275 mGLState.setObjectDirty(GL_PROGRAM);
5276 }
5277}
5278
5279void Context::onTextureChange(const Texture *texture)
5280{
5281 // Conservatively assume all textures are dirty.
5282 // TODO(jmadill): More fine-grained update.
5283 mGLState.setObjectDirty(GL_TEXTURE);
5284}
5285
Jamie Madillc29968b2016-01-20 11:17:23 -05005286} // namespace gl