blob: 1d69e8513d530661e77501666674df5f727c28f0 [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 Madill1b94d432015-08-07 13:23:23 -0400508
Jamie Madill4928b7c2017-06-20 12:57:39 -0400509 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500510
511 Framebuffer *newDefault = nullptr;
512 if (surface != nullptr)
513 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400514 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500515 mCurrentSurface = surface;
516 newDefault = surface->getDefaultFramebuffer();
517 }
518 else
519 {
520 if (mSurfacelessFramebuffer == nullptr)
521 {
522 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
523 }
524
525 newDefault = mSurfacelessFramebuffer;
526 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000527
Corentin Wallez37c39792015-08-20 14:19:46 -0400528 // Update default framebuffer, the binding of the previous default
529 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400530 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700531 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400532 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700533 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400534 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700535 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400536 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700537 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400538 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500539 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400540 }
Ian Ewell292f0052016-02-04 10:37:32 -0500541
542 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400543 mImplementation->onMakeCurrent(this);
544 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000545}
546
Jamie Madill4928b7c2017-06-20 12:57:39 -0400547egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400548{
Corentin Wallez37c39792015-08-20 14:19:46 -0400549 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500550 Framebuffer *currentDefault = nullptr;
551 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400552 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500553 currentDefault = mCurrentSurface->getDefaultFramebuffer();
554 }
555 else if (mSurfacelessFramebuffer != nullptr)
556 {
557 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400558 }
559
Corentin Wallezc295e512017-01-27 17:47:50 -0500560 if (mGLState.getReadFramebuffer() == currentDefault)
561 {
562 mGLState.setReadFramebufferBinding(nullptr);
563 }
564 if (mGLState.getDrawFramebuffer() == currentDefault)
565 {
566 mGLState.setDrawFramebufferBinding(nullptr);
567 }
568 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
569
570 if (mCurrentSurface)
571 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400572 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500573 mCurrentSurface = nullptr;
574 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400575
576 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400577}
578
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000579GLuint Context::createBuffer()
580{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500581 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000582}
583
584GLuint Context::createProgram()
585{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500586 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587}
588
589GLuint Context::createShader(GLenum type)
590{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500591 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592}
593
594GLuint Context::createTexture()
595{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500596 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597}
598
599GLuint Context::createRenderbuffer()
600{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500601 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000602}
603
Sami Väisänene45e53b2016-05-25 10:36:04 +0300604GLuint Context::createPaths(GLsizei range)
605{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500606 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300607 if (resultOrError.isError())
608 {
609 handleError(resultOrError.getError());
610 return 0;
611 }
612 return resultOrError.getResult();
613}
614
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000615// Returns an unused framebuffer name
616GLuint Context::createFramebuffer()
617{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500618 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000619}
620
Jamie Madill33dc8432013-07-26 11:55:05 -0400621GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622{
Jamie Madill33dc8432013-07-26 11:55:05 -0400623 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400624 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625 return handle;
626}
627
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000628void Context::deleteBuffer(GLuint buffer)
629{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500630 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631 {
632 detachBuffer(buffer);
633 }
Jamie Madill893ab082014-05-16 16:56:10 -0400634
Jamie Madill6c1f6712017-02-14 19:08:04 -0500635 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000636}
637
638void Context::deleteShader(GLuint shader)
639{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500640 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641}
642
643void Context::deleteProgram(GLuint program)
644{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500645 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000646}
647
648void Context::deleteTexture(GLuint texture)
649{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500650 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651 {
652 detachTexture(texture);
653 }
654
Jamie Madill6c1f6712017-02-14 19:08:04 -0500655 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656}
657
658void Context::deleteRenderbuffer(GLuint renderbuffer)
659{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500660 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000661 {
662 detachRenderbuffer(renderbuffer);
663 }
Jamie Madill893ab082014-05-16 16:56:10 -0400664
Jamie Madill6c1f6712017-02-14 19:08:04 -0500665 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000666}
667
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400668void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400669{
670 // The spec specifies the underlying Fence object is not deleted until all current
671 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
672 // and since our API is currently designed for being called from a single thread, we can delete
673 // the fence immediately.
Jamie Madill70b5bb02017-08-28 13:32:37 -0400674 mState.mSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400675}
676
Sami Väisänene45e53b2016-05-25 10:36:04 +0300677void Context::deletePaths(GLuint first, GLsizei range)
678{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500679 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300680}
681
682bool Context::hasPathData(GLuint path) const
683{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500684 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300685 if (pathObj == nullptr)
686 return false;
687
688 return pathObj->hasPathData();
689}
690
691bool Context::hasPath(GLuint path) const
692{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500693 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300694}
695
696void Context::setPathCommands(GLuint path,
697 GLsizei numCommands,
698 const GLubyte *commands,
699 GLsizei numCoords,
700 GLenum coordType,
701 const void *coords)
702{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500703 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300704
705 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
706}
707
708void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
709{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500710 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300711
712 switch (pname)
713 {
714 case GL_PATH_STROKE_WIDTH_CHROMIUM:
715 pathObj->setStrokeWidth(value);
716 break;
717 case GL_PATH_END_CAPS_CHROMIUM:
718 pathObj->setEndCaps(static_cast<GLenum>(value));
719 break;
720 case GL_PATH_JOIN_STYLE_CHROMIUM:
721 pathObj->setJoinStyle(static_cast<GLenum>(value));
722 break;
723 case GL_PATH_MITER_LIMIT_CHROMIUM:
724 pathObj->setMiterLimit(value);
725 break;
726 case GL_PATH_STROKE_BOUND_CHROMIUM:
727 pathObj->setStrokeBound(value);
728 break;
729 default:
730 UNREACHABLE();
731 break;
732 }
733}
734
735void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
736{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500737 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300738
739 switch (pname)
740 {
741 case GL_PATH_STROKE_WIDTH_CHROMIUM:
742 *value = pathObj->getStrokeWidth();
743 break;
744 case GL_PATH_END_CAPS_CHROMIUM:
745 *value = static_cast<GLfloat>(pathObj->getEndCaps());
746 break;
747 case GL_PATH_JOIN_STYLE_CHROMIUM:
748 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
749 break;
750 case GL_PATH_MITER_LIMIT_CHROMIUM:
751 *value = pathObj->getMiterLimit();
752 break;
753 case GL_PATH_STROKE_BOUND_CHROMIUM:
754 *value = pathObj->getStrokeBound();
755 break;
756 default:
757 UNREACHABLE();
758 break;
759 }
760}
761
762void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
763{
764 mGLState.setPathStencilFunc(func, ref, mask);
765}
766
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000767void Context::deleteFramebuffer(GLuint framebuffer)
768{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500769 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000770 {
771 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000772 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500773
Jamie Madill6c1f6712017-02-14 19:08:04 -0500774 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000775}
776
Jamie Madill33dc8432013-07-26 11:55:05 -0400777void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000778{
Jamie Madill96a483b2017-06-27 16:49:21 -0400779 FenceNV *fenceObject = nullptr;
780 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000781 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400782 mFenceNVHandleAllocator.release(fence);
783 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000784 }
785}
786
Geoff Lang70d0f492015-12-10 17:45:46 -0500787Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000788{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500789 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000790}
791
Jamie Madill570f7c82014-07-03 10:38:54 -0400792Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500794 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795}
796
Geoff Lang70d0f492015-12-10 17:45:46 -0500797Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500799 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800}
801
Jamie Madill70b5bb02017-08-28 13:32:37 -0400802Sync *Context::getSync(GLsync handle) const
Jamie Madillcd055f82013-07-26 11:55:15 -0400803{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400804 return mState.mSyncs->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400805}
806
Jamie Madill57a89722013-07-02 11:57:03 -0400807VertexArray *Context::getVertexArray(GLuint handle) const
808{
Jamie Madill96a483b2017-06-27 16:49:21 -0400809 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400810}
811
Jamie Madilldc356042013-07-19 16:36:57 -0400812Sampler *Context::getSampler(GLuint handle) const
813{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500814 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400815}
816
Geoff Langc8058452014-02-03 12:04:11 -0500817TransformFeedback *Context::getTransformFeedback(GLuint handle) const
818{
Jamie Madill96a483b2017-06-27 16:49:21 -0400819 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500820}
821
Geoff Lang70d0f492015-12-10 17:45:46 -0500822LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
823{
824 switch (identifier)
825 {
826 case GL_BUFFER:
827 return getBuffer(name);
828 case GL_SHADER:
829 return getShader(name);
830 case GL_PROGRAM:
831 return getProgram(name);
832 case GL_VERTEX_ARRAY:
833 return getVertexArray(name);
834 case GL_QUERY:
835 return getQuery(name);
836 case GL_TRANSFORM_FEEDBACK:
837 return getTransformFeedback(name);
838 case GL_SAMPLER:
839 return getSampler(name);
840 case GL_TEXTURE:
841 return getTexture(name);
842 case GL_RENDERBUFFER:
843 return getRenderbuffer(name);
844 case GL_FRAMEBUFFER:
845 return getFramebuffer(name);
846 default:
847 UNREACHABLE();
848 return nullptr;
849 }
850}
851
852LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
853{
Jamie Madill70b5bb02017-08-28 13:32:37 -0400854 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
Geoff Lang70d0f492015-12-10 17:45:46 -0500855}
856
Martin Radev9d901792016-07-15 15:58:58 +0300857void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
858{
859 LabeledObject *object = getLabeledObject(identifier, name);
860 ASSERT(object != nullptr);
861
862 std::string labelName = GetObjectLabelFromPointer(length, label);
863 object->setLabel(labelName);
864}
865
866void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
867{
868 LabeledObject *object = getLabeledObjectFromPtr(ptr);
869 ASSERT(object != nullptr);
870
871 std::string labelName = GetObjectLabelFromPointer(length, label);
872 object->setLabel(labelName);
873}
874
875void Context::getObjectLabel(GLenum identifier,
876 GLuint name,
877 GLsizei bufSize,
878 GLsizei *length,
879 GLchar *label) const
880{
881 LabeledObject *object = getLabeledObject(identifier, name);
882 ASSERT(object != nullptr);
883
884 const std::string &objectLabel = object->getLabel();
885 GetObjectLabelBase(objectLabel, bufSize, length, label);
886}
887
888void Context::getObjectPtrLabel(const void *ptr,
889 GLsizei bufSize,
890 GLsizei *length,
891 GLchar *label) const
892{
893 LabeledObject *object = getLabeledObjectFromPtr(ptr);
894 ASSERT(object != nullptr);
895
896 const std::string &objectLabel = object->getLabel();
897 GetObjectLabelBase(objectLabel, bufSize, length, label);
898}
899
Jamie Madilldc356042013-07-19 16:36:57 -0400900bool Context::isSampler(GLuint samplerName) const
901{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500902 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400903}
904
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500905void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000906{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500907 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400908 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000909}
910
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800911void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
912{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500913 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400914 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800915}
916
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500917void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000918{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500919 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400920 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000921}
922
Jamie Madilldedd7b92014-11-05 16:30:36 -0500923void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000924{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500925 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000926
Jamie Madilldedd7b92014-11-05 16:30:36 -0500927 if (handle == 0)
928 {
929 texture = mZeroTextures[target].get();
930 }
931 else
932 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500933 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500934 }
935
936 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400937 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000938}
939
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500940void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000941{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500942 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
943 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700944 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000945}
946
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500947void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500949 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
950 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700951 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952}
953
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500954void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400955{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500956 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700957 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400958}
959
Shao80957d92017-02-20 21:25:59 +0800960void Context::bindVertexBuffer(GLuint bindingIndex,
961 GLuint bufferHandle,
962 GLintptr offset,
963 GLsizei stride)
964{
965 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400966 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +0800967}
968
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500969void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400970{
Geoff Lang76b10c92014-09-05 16:28:14 -0400971 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400972 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500973 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400974 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400975}
976
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800977void Context::bindImageTexture(GLuint unit,
978 GLuint texture,
979 GLint level,
980 GLboolean layered,
981 GLint layer,
982 GLenum access,
983 GLenum format)
984{
985 Texture *tex = mState.mTextures->getTexture(texture);
986 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
987}
988
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500989void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000990{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500991 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400992 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000993}
994
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500995void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
996 GLuint index,
997 GLintptr offset,
998 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000999{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001000 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001001 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001002}
1003
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001004void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001005{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001006 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001007 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001008}
1009
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001010void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1011 GLuint index,
1012 GLintptr offset,
1013 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001014{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001015 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001016 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001017}
1018
Jiajia Qin6eafb042016-12-27 17:04:07 +08001019void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1020{
1021 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001022 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001023}
1024
1025void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1026 GLuint index,
1027 GLintptr offset,
1028 GLsizeiptr size)
1029{
1030 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001031 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001032}
1033
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001034void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1035{
1036 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001037 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001038}
1039
1040void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1041 GLuint index,
1042 GLintptr offset,
1043 GLsizeiptr size)
1044{
1045 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001046 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001047}
1048
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001049void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001050{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001051 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001052 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001053}
1054
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001055void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001056{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001057 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001058 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001059}
1060
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001061void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001062{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001063 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001064 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001065}
1066
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001067void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001068{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001069 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001070 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001071}
1072
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001073void Context::useProgram(GLuint program)
1074{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001075 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001076}
1077
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001078void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001079{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001080 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001081 TransformFeedback *transformFeedback =
1082 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001083 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001084}
1085
Jamie Madillf0e04492017-08-26 15:28:42 -04001086void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001087{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001089 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001090
Geoff Lang5aad9672014-09-08 11:10:42 -04001091 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001092 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001093
1094 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001095 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001096}
1097
Jamie Madillf0e04492017-08-26 15:28:42 -04001098void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001099{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001100 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001101 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001102
Jamie Madillf0e04492017-08-26 15:28:42 -04001103 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001104
Geoff Lang5aad9672014-09-08 11:10:42 -04001105 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001106 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001107}
1108
Jamie Madillf0e04492017-08-26 15:28:42 -04001109void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001110{
1111 ASSERT(target == GL_TIMESTAMP_EXT);
1112
1113 Query *queryObject = getQuery(id, true, target);
1114 ASSERT(queryObject);
1115
Jamie Madillf0e04492017-08-26 15:28:42 -04001116 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001117}
1118
1119void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1120{
1121 switch (pname)
1122 {
1123 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001124 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001125 break;
1126 case GL_QUERY_COUNTER_BITS_EXT:
1127 switch (target)
1128 {
1129 case GL_TIME_ELAPSED_EXT:
1130 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1131 break;
1132 case GL_TIMESTAMP_EXT:
1133 params[0] = getExtensions().queryCounterBitsTimestamp;
1134 break;
1135 default:
1136 UNREACHABLE();
1137 params[0] = 0;
1138 break;
1139 }
1140 break;
1141 default:
1142 UNREACHABLE();
1143 return;
1144 }
1145}
1146
Geoff Lang2186c382016-10-14 10:54:54 -04001147void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001148{
Geoff Lang2186c382016-10-14 10:54:54 -04001149 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001150}
1151
Geoff Lang2186c382016-10-14 10:54:54 -04001152void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *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::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *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::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *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 Lang3bf8e3a2016-12-01 17:28:52 -05001167Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001168{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001169 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001170}
1171
Jamie Madill2f348d22017-06-05 10:50:59 -04001172FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173{
Jamie Madill96a483b2017-06-27 16:49:21 -04001174 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175}
1176
Jamie Madill2f348d22017-06-05 10:50:59 -04001177Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001178{
Jamie Madill96a483b2017-06-27 16:49:21 -04001179 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001180 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001181 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001182 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001183
1184 Query *query = mQueryMap.query(handle);
1185 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001187 query = new Query(mImplementation->createQuery(type), handle);
1188 query->addRef();
1189 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001190 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001191 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001192}
1193
Geoff Lang70d0f492015-12-10 17:45:46 -05001194Query *Context::getQuery(GLuint handle) const
1195{
Jamie Madill96a483b2017-06-27 16:49:21 -04001196 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001197}
1198
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001199Texture *Context::getTargetTexture(GLenum target) const
1200{
Ian Ewellbda75592016-04-18 17:25:54 -04001201 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001202 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001203}
1204
Geoff Lang76b10c92014-09-05 16:28:14 -04001205Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001207 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001208}
1209
Geoff Lang492a7e42014-11-05 13:27:06 -05001210Compiler *Context::getCompiler() const
1211{
Jamie Madill2f348d22017-06-05 10:50:59 -04001212 if (mCompiler.get() == nullptr)
1213 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001214 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001215 }
1216 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001217}
1218
Jamie Madillc1d770e2017-04-13 17:31:24 -04001219void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001220{
1221 switch (pname)
1222 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001223 case GL_SHADER_COMPILER:
1224 *params = GL_TRUE;
1225 break;
1226 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1227 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1228 break;
1229 default:
1230 mGLState.getBooleanv(pname, params);
1231 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233}
1234
Jamie Madillc1d770e2017-04-13 17:31:24 -04001235void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236{
Shannon Woods53a94a82014-06-24 15:20:36 -04001237 // Queries about context capabilities and maximums are answered by Context.
1238 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001239 switch (pname)
1240 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001241 case GL_ALIASED_LINE_WIDTH_RANGE:
1242 params[0] = mCaps.minAliasedLineWidth;
1243 params[1] = mCaps.maxAliasedLineWidth;
1244 break;
1245 case GL_ALIASED_POINT_SIZE_RANGE:
1246 params[0] = mCaps.minAliasedPointSize;
1247 params[1] = mCaps.maxAliasedPointSize;
1248 break;
1249 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1250 ASSERT(mExtensions.textureFilterAnisotropic);
1251 *params = mExtensions.maxTextureAnisotropy;
1252 break;
1253 case GL_MAX_TEXTURE_LOD_BIAS:
1254 *params = mCaps.maxLODBias;
1255 break;
1256
1257 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1258 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1259 {
1260 ASSERT(mExtensions.pathRendering);
1261 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1262 memcpy(params, m, 16 * sizeof(GLfloat));
1263 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001264 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001265
Jamie Madill231c7f52017-04-26 13:45:37 -04001266 default:
1267 mGLState.getFloatv(pname, params);
1268 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001269 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270}
1271
Jamie Madillc1d770e2017-04-13 17:31:24 -04001272void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273{
Shannon Woods53a94a82014-06-24 15:20:36 -04001274 // Queries about context capabilities and maximums are answered by Context.
1275 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001276
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277 switch (pname)
1278 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001279 case GL_MAX_VERTEX_ATTRIBS:
1280 *params = mCaps.maxVertexAttributes;
1281 break;
1282 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1283 *params = mCaps.maxVertexUniformVectors;
1284 break;
1285 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1286 *params = mCaps.maxVertexUniformComponents;
1287 break;
1288 case GL_MAX_VARYING_VECTORS:
1289 *params = mCaps.maxVaryingVectors;
1290 break;
1291 case GL_MAX_VARYING_COMPONENTS:
1292 *params = mCaps.maxVertexOutputComponents;
1293 break;
1294 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1295 *params = mCaps.maxCombinedTextureImageUnits;
1296 break;
1297 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1298 *params = mCaps.maxVertexTextureImageUnits;
1299 break;
1300 case GL_MAX_TEXTURE_IMAGE_UNITS:
1301 *params = mCaps.maxTextureImageUnits;
1302 break;
1303 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1304 *params = mCaps.maxFragmentUniformVectors;
1305 break;
1306 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1307 *params = mCaps.maxFragmentUniformComponents;
1308 break;
1309 case GL_MAX_RENDERBUFFER_SIZE:
1310 *params = mCaps.maxRenderbufferSize;
1311 break;
1312 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1313 *params = mCaps.maxColorAttachments;
1314 break;
1315 case GL_MAX_DRAW_BUFFERS_EXT:
1316 *params = mCaps.maxDrawBuffers;
1317 break;
1318 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1319 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1320 case GL_SUBPIXEL_BITS:
1321 *params = 4;
1322 break;
1323 case GL_MAX_TEXTURE_SIZE:
1324 *params = mCaps.max2DTextureSize;
1325 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001326 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1327 *params = mCaps.maxRectangleTextureSize;
1328 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001329 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1330 *params = mCaps.maxCubeMapTextureSize;
1331 break;
1332 case GL_MAX_3D_TEXTURE_SIZE:
1333 *params = mCaps.max3DTextureSize;
1334 break;
1335 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1336 *params = mCaps.maxArrayTextureLayers;
1337 break;
1338 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1339 *params = mCaps.uniformBufferOffsetAlignment;
1340 break;
1341 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1342 *params = mCaps.maxUniformBufferBindings;
1343 break;
1344 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1345 *params = mCaps.maxVertexUniformBlocks;
1346 break;
1347 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1348 *params = mCaps.maxFragmentUniformBlocks;
1349 break;
1350 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1351 *params = mCaps.maxCombinedTextureImageUnits;
1352 break;
1353 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1354 *params = mCaps.maxVertexOutputComponents;
1355 break;
1356 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1357 *params = mCaps.maxFragmentInputComponents;
1358 break;
1359 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1360 *params = mCaps.minProgramTexelOffset;
1361 break;
1362 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1363 *params = mCaps.maxProgramTexelOffset;
1364 break;
1365 case GL_MAJOR_VERSION:
1366 *params = getClientVersion().major;
1367 break;
1368 case GL_MINOR_VERSION:
1369 *params = getClientVersion().minor;
1370 break;
1371 case GL_MAX_ELEMENTS_INDICES:
1372 *params = mCaps.maxElementsIndices;
1373 break;
1374 case GL_MAX_ELEMENTS_VERTICES:
1375 *params = mCaps.maxElementsVertices;
1376 break;
1377 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1378 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1379 break;
1380 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1381 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1382 break;
1383 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1384 *params = mCaps.maxTransformFeedbackSeparateComponents;
1385 break;
1386 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1387 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1388 break;
1389 case GL_MAX_SAMPLES_ANGLE:
1390 *params = mCaps.maxSamples;
1391 break;
1392 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001393 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001394 params[0] = mCaps.maxViewportWidth;
1395 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001396 }
1397 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001398 case GL_COMPRESSED_TEXTURE_FORMATS:
1399 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1400 params);
1401 break;
1402 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1403 *params = mResetStrategy;
1404 break;
1405 case GL_NUM_SHADER_BINARY_FORMATS:
1406 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1407 break;
1408 case GL_SHADER_BINARY_FORMATS:
1409 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1410 break;
1411 case GL_NUM_PROGRAM_BINARY_FORMATS:
1412 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1413 break;
1414 case GL_PROGRAM_BINARY_FORMATS:
1415 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1416 break;
1417 case GL_NUM_EXTENSIONS:
1418 *params = static_cast<GLint>(mExtensionStrings.size());
1419 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001420
Jamie Madill231c7f52017-04-26 13:45:37 -04001421 // GL_KHR_debug
1422 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1423 *params = mExtensions.maxDebugMessageLength;
1424 break;
1425 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1426 *params = mExtensions.maxDebugLoggedMessages;
1427 break;
1428 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1429 *params = mExtensions.maxDebugGroupStackDepth;
1430 break;
1431 case GL_MAX_LABEL_LENGTH:
1432 *params = mExtensions.maxLabelLength;
1433 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001434
Martin Radeve5285d22017-07-14 16:23:53 +03001435 // GL_ANGLE_multiview
1436 case GL_MAX_VIEWS_ANGLE:
1437 *params = mExtensions.maxViews;
1438 break;
1439
Jamie Madill231c7f52017-04-26 13:45:37 -04001440 // GL_EXT_disjoint_timer_query
1441 case GL_GPU_DISJOINT_EXT:
1442 *params = mImplementation->getGPUDisjoint();
1443 break;
1444 case GL_MAX_FRAMEBUFFER_WIDTH:
1445 *params = mCaps.maxFramebufferWidth;
1446 break;
1447 case GL_MAX_FRAMEBUFFER_HEIGHT:
1448 *params = mCaps.maxFramebufferHeight;
1449 break;
1450 case GL_MAX_FRAMEBUFFER_SAMPLES:
1451 *params = mCaps.maxFramebufferSamples;
1452 break;
1453 case GL_MAX_SAMPLE_MASK_WORDS:
1454 *params = mCaps.maxSampleMaskWords;
1455 break;
1456 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1457 *params = mCaps.maxColorTextureSamples;
1458 break;
1459 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1460 *params = mCaps.maxDepthTextureSamples;
1461 break;
1462 case GL_MAX_INTEGER_SAMPLES:
1463 *params = mCaps.maxIntegerSamples;
1464 break;
1465 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1466 *params = mCaps.maxVertexAttribRelativeOffset;
1467 break;
1468 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1469 *params = mCaps.maxVertexAttribBindings;
1470 break;
1471 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1472 *params = mCaps.maxVertexAttribStride;
1473 break;
1474 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1475 *params = mCaps.maxVertexAtomicCounterBuffers;
1476 break;
1477 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1478 *params = mCaps.maxVertexAtomicCounters;
1479 break;
1480 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1481 *params = mCaps.maxVertexImageUniforms;
1482 break;
1483 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1484 *params = mCaps.maxVertexShaderStorageBlocks;
1485 break;
1486 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1487 *params = mCaps.maxFragmentAtomicCounterBuffers;
1488 break;
1489 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1490 *params = mCaps.maxFragmentAtomicCounters;
1491 break;
1492 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1493 *params = mCaps.maxFragmentImageUniforms;
1494 break;
1495 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1496 *params = mCaps.maxFragmentShaderStorageBlocks;
1497 break;
1498 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1499 *params = mCaps.minProgramTextureGatherOffset;
1500 break;
1501 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1502 *params = mCaps.maxProgramTextureGatherOffset;
1503 break;
1504 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1505 *params = mCaps.maxComputeWorkGroupInvocations;
1506 break;
1507 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1508 *params = mCaps.maxComputeUniformBlocks;
1509 break;
1510 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1511 *params = mCaps.maxComputeTextureImageUnits;
1512 break;
1513 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1514 *params = mCaps.maxComputeSharedMemorySize;
1515 break;
1516 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1517 *params = mCaps.maxComputeUniformComponents;
1518 break;
1519 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1520 *params = mCaps.maxComputeAtomicCounterBuffers;
1521 break;
1522 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1523 *params = mCaps.maxComputeAtomicCounters;
1524 break;
1525 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1526 *params = mCaps.maxComputeImageUniforms;
1527 break;
1528 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1529 *params = mCaps.maxCombinedComputeUniformComponents;
1530 break;
1531 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1532 *params = mCaps.maxComputeShaderStorageBlocks;
1533 break;
1534 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1535 *params = mCaps.maxCombinedShaderOutputResources;
1536 break;
1537 case GL_MAX_UNIFORM_LOCATIONS:
1538 *params = mCaps.maxUniformLocations;
1539 break;
1540 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1541 *params = mCaps.maxAtomicCounterBufferBindings;
1542 break;
1543 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1544 *params = mCaps.maxAtomicCounterBufferSize;
1545 break;
1546 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1547 *params = mCaps.maxCombinedAtomicCounterBuffers;
1548 break;
1549 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1550 *params = mCaps.maxCombinedAtomicCounters;
1551 break;
1552 case GL_MAX_IMAGE_UNITS:
1553 *params = mCaps.maxImageUnits;
1554 break;
1555 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1556 *params = mCaps.maxCombinedImageUniforms;
1557 break;
1558 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1559 *params = mCaps.maxShaderStorageBufferBindings;
1560 break;
1561 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1562 *params = mCaps.maxCombinedShaderStorageBlocks;
1563 break;
1564 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1565 *params = mCaps.shaderStorageBufferOffsetAlignment;
1566 break;
1567 default:
1568 mGLState.getIntegerv(this, pname, params);
1569 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001570 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001571}
1572
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001573void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001574{
Shannon Woods53a94a82014-06-24 15:20:36 -04001575 // Queries about context capabilities and maximums are answered by Context.
1576 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001577 switch (pname)
1578 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001579 case GL_MAX_ELEMENT_INDEX:
1580 *params = mCaps.maxElementIndex;
1581 break;
1582 case GL_MAX_UNIFORM_BLOCK_SIZE:
1583 *params = mCaps.maxUniformBlockSize;
1584 break;
1585 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1586 *params = mCaps.maxCombinedVertexUniformComponents;
1587 break;
1588 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1589 *params = mCaps.maxCombinedFragmentUniformComponents;
1590 break;
1591 case GL_MAX_SERVER_WAIT_TIMEOUT:
1592 *params = mCaps.maxServerWaitTimeout;
1593 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001594
Jamie Madill231c7f52017-04-26 13:45:37 -04001595 // GL_EXT_disjoint_timer_query
1596 case GL_TIMESTAMP_EXT:
1597 *params = mImplementation->getTimestamp();
1598 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001599
Jamie Madill231c7f52017-04-26 13:45:37 -04001600 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1601 *params = mCaps.maxShaderStorageBlockSize;
1602 break;
1603 default:
1604 UNREACHABLE();
1605 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001606 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001607}
1608
Geoff Lang70d0f492015-12-10 17:45:46 -05001609void Context::getPointerv(GLenum pname, void **params) const
1610{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001611 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001612}
1613
Martin Radev66fb8202016-07-28 11:45:20 +03001614void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001615{
Shannon Woods53a94a82014-06-24 15:20:36 -04001616 // Queries about context capabilities and maximums are answered by Context.
1617 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001618
1619 GLenum nativeType;
1620 unsigned int numParams;
1621 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1622 ASSERT(queryStatus);
1623
1624 if (nativeType == GL_INT)
1625 {
1626 switch (target)
1627 {
1628 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1629 ASSERT(index < 3u);
1630 *data = mCaps.maxComputeWorkGroupCount[index];
1631 break;
1632 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1633 ASSERT(index < 3u);
1634 *data = mCaps.maxComputeWorkGroupSize[index];
1635 break;
1636 default:
1637 mGLState.getIntegeri_v(target, index, data);
1638 }
1639 }
1640 else
1641 {
1642 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1643 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001644}
1645
Martin Radev66fb8202016-07-28 11:45:20 +03001646void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001647{
Shannon Woods53a94a82014-06-24 15:20:36 -04001648 // Queries about context capabilities and maximums are answered by Context.
1649 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001650
1651 GLenum nativeType;
1652 unsigned int numParams;
1653 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1654 ASSERT(queryStatus);
1655
1656 if (nativeType == GL_INT_64_ANGLEX)
1657 {
1658 mGLState.getInteger64i_v(target, index, data);
1659 }
1660 else
1661 {
1662 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1663 }
1664}
1665
1666void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1667{
1668 // Queries about context capabilities and maximums are answered by Context.
1669 // Queries about current GL state values are answered by State.
1670
1671 GLenum nativeType;
1672 unsigned int numParams;
1673 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1674 ASSERT(queryStatus);
1675
1676 if (nativeType == GL_BOOL)
1677 {
1678 mGLState.getBooleani_v(target, index, data);
1679 }
1680 else
1681 {
1682 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1683 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001684}
1685
He Yunchao010e4db2017-03-03 14:22:06 +08001686void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1687{
1688 Buffer *buffer = mGLState.getTargetBuffer(target);
1689 QueryBufferParameteriv(buffer, pname, params);
1690}
1691
1692void Context::getFramebufferAttachmentParameteriv(GLenum target,
1693 GLenum attachment,
1694 GLenum pname,
1695 GLint *params)
1696{
1697 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1698 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1699}
1700
1701void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1702{
1703 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1704 QueryRenderbufferiv(this, renderbuffer, pname, params);
1705}
1706
1707void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1708{
1709 Texture *texture = getTargetTexture(target);
1710 QueryTexParameterfv(texture, pname, params);
1711}
1712
1713void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1714{
1715 Texture *texture = getTargetTexture(target);
1716 QueryTexParameteriv(texture, pname, params);
1717}
1718void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1719{
1720 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001721 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001722}
1723
1724void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1725{
1726 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001727 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001728}
1729
1730void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1731{
1732 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001733 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001734}
1735
1736void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1737{
1738 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001739 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001740}
1741
Jamie Madill675fe712016-12-19 13:07:54 -05001742void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001743{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001744 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001745 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1746 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001747}
1748
Jamie Madill675fe712016-12-19 13:07:54 -05001749void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001750{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001751 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001752 ANGLE_CONTEXT_TRY(
1753 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1754 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001755}
1756
Jamie Madill876429b2017-04-20 15:46:24 -04001757void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001758{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001759 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001760 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001761}
1762
Jamie Madill675fe712016-12-19 13:07:54 -05001763void Context::drawElementsInstanced(GLenum mode,
1764 GLsizei count,
1765 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001766 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001767 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001768{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001769 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001770 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001771 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001772}
1773
Jamie Madill675fe712016-12-19 13:07:54 -05001774void Context::drawRangeElements(GLenum mode,
1775 GLuint start,
1776 GLuint end,
1777 GLsizei count,
1778 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001779 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001780{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001781 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001782 ANGLE_CONTEXT_TRY(
1783 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001784}
1785
Jamie Madill876429b2017-04-20 15:46:24 -04001786void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001787{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001788 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001789 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001790}
1791
Jamie Madill876429b2017-04-20 15:46:24 -04001792void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001793{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001794 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001795 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001796}
1797
Jamie Madill675fe712016-12-19 13:07:54 -05001798void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001799{
Jamie Madill675fe712016-12-19 13:07:54 -05001800 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001801}
1802
Jamie Madill675fe712016-12-19 13:07:54 -05001803void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001804{
Jamie Madill675fe712016-12-19 13:07:54 -05001805 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001806}
1807
Austin Kinross6ee1e782015-05-29 17:05:37 -07001808void Context::insertEventMarker(GLsizei length, const char *marker)
1809{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001810 ASSERT(mImplementation);
1811 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001812}
1813
1814void Context::pushGroupMarker(GLsizei length, const char *marker)
1815{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001816 ASSERT(mImplementation);
1817 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001818}
1819
1820void Context::popGroupMarker()
1821{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001822 ASSERT(mImplementation);
1823 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001824}
1825
Geoff Langd8605522016-04-13 10:19:12 -04001826void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1827{
1828 Program *programObject = getProgram(program);
1829 ASSERT(programObject);
1830
1831 programObject->bindUniformLocation(location, name);
1832}
1833
Sami Väisänena797e062016-05-12 15:23:40 +03001834void Context::setCoverageModulation(GLenum components)
1835{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001836 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001837}
1838
Sami Väisänene45e53b2016-05-25 10:36:04 +03001839void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1840{
1841 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1842}
1843
1844void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1845{
1846 GLfloat I[16];
1847 angle::Matrix<GLfloat>::setToIdentity(I);
1848
1849 mGLState.loadPathRenderingMatrix(matrixMode, I);
1850}
1851
1852void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1853{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001854 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001855 if (!pathObj)
1856 return;
1857
1858 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1859 syncRendererState();
1860
1861 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1862}
1863
1864void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1865{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001866 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001867 if (!pathObj)
1868 return;
1869
1870 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1871 syncRendererState();
1872
1873 mImplementation->stencilStrokePath(pathObj, reference, mask);
1874}
1875
1876void Context::coverFillPath(GLuint path, GLenum coverMode)
1877{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001878 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001879 if (!pathObj)
1880 return;
1881
1882 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1883 syncRendererState();
1884
1885 mImplementation->coverFillPath(pathObj, coverMode);
1886}
1887
1888void Context::coverStrokePath(GLuint path, GLenum coverMode)
1889{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001890 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001891 if (!pathObj)
1892 return;
1893
1894 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1895 syncRendererState();
1896
1897 mImplementation->coverStrokePath(pathObj, coverMode);
1898}
1899
1900void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1901{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001902 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001903 if (!pathObj)
1904 return;
1905
1906 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1907 syncRendererState();
1908
1909 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1910}
1911
1912void Context::stencilThenCoverStrokePath(GLuint path,
1913 GLint reference,
1914 GLuint mask,
1915 GLenum coverMode)
1916{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001917 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001918 if (!pathObj)
1919 return;
1920
1921 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1922 syncRendererState();
1923
1924 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1925}
1926
Sami Väisänend59ca052016-06-21 16:10:00 +03001927void Context::coverFillPathInstanced(GLsizei numPaths,
1928 GLenum pathNameType,
1929 const void *paths,
1930 GLuint pathBase,
1931 GLenum coverMode,
1932 GLenum transformType,
1933 const GLfloat *transformValues)
1934{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001935 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001936
1937 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1938 syncRendererState();
1939
1940 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1941}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001942
Sami Väisänend59ca052016-06-21 16:10:00 +03001943void Context::coverStrokePathInstanced(GLsizei numPaths,
1944 GLenum pathNameType,
1945 const void *paths,
1946 GLuint pathBase,
1947 GLenum coverMode,
1948 GLenum transformType,
1949 const GLfloat *transformValues)
1950{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001951 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001952
1953 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1954 syncRendererState();
1955
1956 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1957 transformValues);
1958}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001959
Sami Väisänend59ca052016-06-21 16:10:00 +03001960void Context::stencilFillPathInstanced(GLsizei numPaths,
1961 GLenum pathNameType,
1962 const void *paths,
1963 GLuint pathBase,
1964 GLenum fillMode,
1965 GLuint mask,
1966 GLenum transformType,
1967 const GLfloat *transformValues)
1968{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001969 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001970
1971 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1972 syncRendererState();
1973
1974 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1975 transformValues);
1976}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001977
Sami Väisänend59ca052016-06-21 16:10:00 +03001978void Context::stencilStrokePathInstanced(GLsizei numPaths,
1979 GLenum pathNameType,
1980 const void *paths,
1981 GLuint pathBase,
1982 GLint reference,
1983 GLuint mask,
1984 GLenum transformType,
1985 const GLfloat *transformValues)
1986{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001987 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001988
1989 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1990 syncRendererState();
1991
1992 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1993 transformValues);
1994}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001995
Sami Väisänend59ca052016-06-21 16:10:00 +03001996void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1997 GLenum pathNameType,
1998 const void *paths,
1999 GLuint pathBase,
2000 GLenum fillMode,
2001 GLuint mask,
2002 GLenum coverMode,
2003 GLenum transformType,
2004 const GLfloat *transformValues)
2005{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002006 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002007
2008 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2009 syncRendererState();
2010
2011 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2012 transformType, transformValues);
2013}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002014
Sami Väisänend59ca052016-06-21 16:10:00 +03002015void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2016 GLenum pathNameType,
2017 const void *paths,
2018 GLuint pathBase,
2019 GLint reference,
2020 GLuint mask,
2021 GLenum coverMode,
2022 GLenum transformType,
2023 const GLfloat *transformValues)
2024{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002025 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002026
2027 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2028 syncRendererState();
2029
2030 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2031 transformType, transformValues);
2032}
2033
Sami Väisänen46eaa942016-06-29 10:26:37 +03002034void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2035{
2036 auto *programObject = getProgram(program);
2037
2038 programObject->bindFragmentInputLocation(location, name);
2039}
2040
2041void Context::programPathFragmentInputGen(GLuint program,
2042 GLint location,
2043 GLenum genMode,
2044 GLint components,
2045 const GLfloat *coeffs)
2046{
2047 auto *programObject = getProgram(program);
2048
Jamie Madillbd044ed2017-06-05 12:59:21 -04002049 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002050}
2051
jchen1015015f72017-03-16 13:54:21 +08002052GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2053{
jchen10fd7c3b52017-03-21 15:36:03 +08002054 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002055 return QueryProgramResourceIndex(programObject, programInterface, name);
2056}
2057
jchen10fd7c3b52017-03-21 15:36:03 +08002058void Context::getProgramResourceName(GLuint program,
2059 GLenum programInterface,
2060 GLuint index,
2061 GLsizei bufSize,
2062 GLsizei *length,
2063 GLchar *name)
2064{
2065 const auto *programObject = getProgram(program);
2066 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2067}
2068
jchen10191381f2017-04-11 13:59:04 +08002069GLint Context::getProgramResourceLocation(GLuint program,
2070 GLenum programInterface,
2071 const GLchar *name)
2072{
2073 const auto *programObject = getProgram(program);
2074 return QueryProgramResourceLocation(programObject, programInterface, name);
2075}
2076
jchen10880683b2017-04-12 16:21:55 +08002077void Context::getProgramResourceiv(GLuint program,
2078 GLenum programInterface,
2079 GLuint index,
2080 GLsizei propCount,
2081 const GLenum *props,
2082 GLsizei bufSize,
2083 GLsizei *length,
2084 GLint *params)
2085{
2086 const auto *programObject = getProgram(program);
2087 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2088 length, params);
2089}
2090
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002091Error Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002092{
Geoff Langda5777c2014-07-11 09:52:58 -04002093 if (error.isError())
2094 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002095 GLenum code = error.getCode();
2096 mErrors.insert(code);
2097 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2098 {
2099 markContextLost();
2100 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002101
2102 if (!error.getMessage().empty())
2103 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002104 auto *debug = &mGLState.getDebug();
2105 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2106 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002107 }
Geoff Langda5777c2014-07-11 09:52:58 -04002108 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002109
2110 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002111}
2112
2113// Get one of the recorded errors and clear its flag, if any.
2114// [OpenGL ES 2.0.24] section 2.5 page 13.
2115GLenum Context::getError()
2116{
Geoff Langda5777c2014-07-11 09:52:58 -04002117 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002118 {
Geoff Langda5777c2014-07-11 09:52:58 -04002119 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002120 }
Geoff Langda5777c2014-07-11 09:52:58 -04002121 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002122 {
Geoff Langda5777c2014-07-11 09:52:58 -04002123 GLenum error = *mErrors.begin();
2124 mErrors.erase(mErrors.begin());
2125 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002126 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002127}
2128
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002129// NOTE: this function should not assume that this context is current!
2130void Context::markContextLost()
2131{
2132 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002133 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002134 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002135 mContextLostForced = true;
2136 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002137 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002138}
2139
2140bool Context::isContextLost()
2141{
2142 return mContextLost;
2143}
2144
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002145GLenum Context::getResetStatus()
2146{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002147 // Even if the application doesn't want to know about resets, we want to know
2148 // as it will allow us to skip all the calls.
2149 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002150 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002151 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002152 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002153 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002154 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002155
2156 // EXT_robustness, section 2.6: If the reset notification behavior is
2157 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2158 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2159 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002160 }
2161
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002162 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2163 // status should be returned at least once, and GL_NO_ERROR should be returned
2164 // once the device has finished resetting.
2165 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002166 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002167 ASSERT(mResetStatus == GL_NO_ERROR);
2168 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002169
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002170 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002171 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002172 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002173 }
2174 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002175 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002176 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002177 // If markContextLost was used to mark the context lost then
2178 // assume that is not recoverable, and continue to report the
2179 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002180 mResetStatus = mImplementation->getResetStatus();
2181 }
Jamie Madill893ab082014-05-16 16:56:10 -04002182
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002183 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002184}
2185
2186bool Context::isResetNotificationEnabled()
2187{
2188 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2189}
2190
Corentin Walleze3b10e82015-05-20 11:06:25 -04002191const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002192{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002193 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002194}
2195
2196EGLenum Context::getClientType() const
2197{
2198 return mClientType;
2199}
2200
2201EGLenum Context::getRenderBuffer() const
2202{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002203 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2204 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002205 {
2206 return EGL_NONE;
2207 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002208
2209 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2210 ASSERT(backAttachment != nullptr);
2211 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002212}
2213
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002214VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002215{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002216 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002217 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2218 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002219 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002220 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2221 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002222
Jamie Madill96a483b2017-06-27 16:49:21 -04002223 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002224 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002225
2226 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002227}
2228
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002229TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002230{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002231 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002232 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2233 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002234 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002235 transformFeedback =
2236 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002237 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002238 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002239 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002240
2241 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002242}
2243
2244bool Context::isVertexArrayGenerated(GLuint vertexArray)
2245{
Jamie Madill96a483b2017-06-27 16:49:21 -04002246 ASSERT(mVertexArrayMap.contains(0));
2247 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002248}
2249
2250bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2251{
Jamie Madill96a483b2017-06-27 16:49:21 -04002252 ASSERT(mTransformFeedbackMap.contains(0));
2253 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002254}
2255
Shannon Woods53a94a82014-06-24 15:20:36 -04002256void Context::detachTexture(GLuint texture)
2257{
2258 // Simple pass-through to State's detachTexture method, as textures do not require
2259 // allocation map management either here or in the resource manager at detach time.
2260 // Zero textures are held by the Context, and we don't attempt to request them from
2261 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002262 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002263}
2264
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002265void Context::detachBuffer(GLuint buffer)
2266{
Yuly Novikov5807a532015-12-03 13:01:22 -05002267 // Simple pass-through to State's detachBuffer method, since
2268 // only buffer attachments to container objects that are bound to the current context
2269 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002270
Yuly Novikov5807a532015-12-03 13:01:22 -05002271 // [OpenGL ES 3.2] section 5.1.2 page 45:
2272 // Attachments to unbound container objects, such as
2273 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2274 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002275 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002276}
2277
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002278void Context::detachFramebuffer(GLuint framebuffer)
2279{
Shannon Woods53a94a82014-06-24 15:20:36 -04002280 // Framebuffer detachment is handled by Context, because 0 is a valid
2281 // Framebuffer object, and a pointer to it must be passed from Context
2282 // to State at binding time.
2283
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002284 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002285 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2286 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2287 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002288
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002289 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002290 {
2291 bindReadFramebuffer(0);
2292 }
2293
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002294 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002295 {
2296 bindDrawFramebuffer(0);
2297 }
2298}
2299
2300void Context::detachRenderbuffer(GLuint renderbuffer)
2301{
Jamie Madilla02315b2017-02-23 14:14:47 -05002302 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002303}
2304
Jamie Madill57a89722013-07-02 11:57:03 -04002305void Context::detachVertexArray(GLuint vertexArray)
2306{
Jamie Madill77a72f62015-04-14 11:18:32 -04002307 // Vertex array detachment is handled by Context, because 0 is a valid
2308 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002309 // binding time.
2310
Jamie Madill57a89722013-07-02 11:57:03 -04002311 // [OpenGL ES 3.0.2] section 2.10 page 43:
2312 // If a vertex array object that is currently bound is deleted, the binding
2313 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002314 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002315 {
2316 bindVertexArray(0);
2317 }
2318}
2319
Geoff Langc8058452014-02-03 12:04:11 -05002320void Context::detachTransformFeedback(GLuint transformFeedback)
2321{
Corentin Walleza2257da2016-04-19 16:43:12 -04002322 // Transform feedback detachment is handled by Context, because 0 is a valid
2323 // transform feedback, and a pointer to it must be passed from Context to State at
2324 // binding time.
2325
2326 // The OpenGL specification doesn't mention what should happen when the currently bound
2327 // transform feedback object is deleted. Since it is a container object, we treat it like
2328 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002329 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002330 {
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04002331 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Corentin Walleza2257da2016-04-19 16:43:12 -04002332 }
Geoff Langc8058452014-02-03 12:04:11 -05002333}
2334
Jamie Madilldc356042013-07-19 16:36:57 -04002335void Context::detachSampler(GLuint sampler)
2336{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002337 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002338}
2339
Jamie Madill3ef140a2017-08-26 23:11:21 -04002340void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002341{
Shaodde78e82017-05-22 14:13:27 +08002342 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002343}
2344
Jamie Madille29d1672013-07-19 16:36:57 -04002345void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2346{
Geoff Langc1984ed2016-10-07 12:41:00 -04002347 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002348 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002349 SetSamplerParameteri(samplerObject, pname, param);
2350}
Jamie Madille29d1672013-07-19 16:36:57 -04002351
Geoff Langc1984ed2016-10-07 12:41:00 -04002352void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2353{
2354 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002355 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002356 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002357}
2358
2359void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2360{
Geoff Langc1984ed2016-10-07 12:41:00 -04002361 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002362 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002363 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002364}
2365
Geoff Langc1984ed2016-10-07 12:41:00 -04002366void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002367{
Geoff Langc1984ed2016-10-07 12:41:00 -04002368 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002369 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002370 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002371}
2372
Geoff Langc1984ed2016-10-07 12:41:00 -04002373void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002374{
Geoff Langc1984ed2016-10-07 12:41:00 -04002375 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002376 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002377 QuerySamplerParameteriv(samplerObject, pname, params);
2378}
Jamie Madill9675b802013-07-19 16:36:59 -04002379
Geoff Langc1984ed2016-10-07 12:41:00 -04002380void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2381{
2382 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002383 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002384 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002385}
2386
Olli Etuahof0fee072016-03-30 15:11:58 +03002387void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2388{
2389 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002390 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002391}
2392
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002393void Context::initRendererString()
2394{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002395 std::ostringstream rendererString;
2396 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002397 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002398 rendererString << ")";
2399
Geoff Langcec35902014-04-16 10:52:36 -04002400 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002401}
2402
Geoff Langc339c4e2016-11-29 10:37:36 -05002403void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002404{
Geoff Langc339c4e2016-11-29 10:37:36 -05002405 const Version &clientVersion = getClientVersion();
2406
2407 std::ostringstream versionString;
2408 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2409 << ANGLE_VERSION_STRING << ")";
2410 mVersionString = MakeStaticString(versionString.str());
2411
2412 std::ostringstream shadingLanguageVersionString;
2413 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2414 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2415 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2416 << ")";
2417 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002418}
2419
Geoff Langcec35902014-04-16 10:52:36 -04002420void Context::initExtensionStrings()
2421{
Geoff Langc339c4e2016-11-29 10:37:36 -05002422 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2423 std::ostringstream combinedStringStream;
2424 std::copy(strings.begin(), strings.end(),
2425 std::ostream_iterator<const char *>(combinedStringStream, " "));
2426 return MakeStaticString(combinedStringStream.str());
2427 };
2428
2429 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002430 for (const auto &extensionString : mExtensions.getStrings())
2431 {
2432 mExtensionStrings.push_back(MakeStaticString(extensionString));
2433 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002434 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002435
Bryan Bernhart58806562017-01-05 13:09:31 -08002436 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2437
Geoff Langc339c4e2016-11-29 10:37:36 -05002438 mRequestableExtensionStrings.clear();
2439 for (const auto &extensionInfo : GetExtensionInfoMap())
2440 {
2441 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002442 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2443 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002444 {
2445 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2446 }
2447 }
2448 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002449}
2450
Geoff Langc339c4e2016-11-29 10:37:36 -05002451const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002452{
Geoff Langc339c4e2016-11-29 10:37:36 -05002453 switch (name)
2454 {
2455 case GL_VENDOR:
2456 return reinterpret_cast<const GLubyte *>("Google Inc.");
2457
2458 case GL_RENDERER:
2459 return reinterpret_cast<const GLubyte *>(mRendererString);
2460
2461 case GL_VERSION:
2462 return reinterpret_cast<const GLubyte *>(mVersionString);
2463
2464 case GL_SHADING_LANGUAGE_VERSION:
2465 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2466
2467 case GL_EXTENSIONS:
2468 return reinterpret_cast<const GLubyte *>(mExtensionString);
2469
2470 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2471 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2472
2473 default:
2474 UNREACHABLE();
2475 return nullptr;
2476 }
Geoff Langcec35902014-04-16 10:52:36 -04002477}
2478
Geoff Langc339c4e2016-11-29 10:37:36 -05002479const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002480{
Geoff Langc339c4e2016-11-29 10:37:36 -05002481 switch (name)
2482 {
2483 case GL_EXTENSIONS:
2484 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2485
2486 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2487 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2488
2489 default:
2490 UNREACHABLE();
2491 return nullptr;
2492 }
Geoff Langcec35902014-04-16 10:52:36 -04002493}
2494
2495size_t Context::getExtensionStringCount() const
2496{
2497 return mExtensionStrings.size();
2498}
2499
Geoff Langc339c4e2016-11-29 10:37:36 -05002500void Context::requestExtension(const char *name)
2501{
2502 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2503 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2504 const auto &extension = extensionInfos.at(name);
2505 ASSERT(extension.Requestable);
2506
2507 if (mExtensions.*(extension.ExtensionsMember))
2508 {
2509 // Extension already enabled
2510 return;
2511 }
2512
2513 mExtensions.*(extension.ExtensionsMember) = true;
2514 updateCaps();
2515 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002516
Jamie Madill2f348d22017-06-05 10:50:59 -04002517 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2518 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002519
2520 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2521 // formats renderable or sampleable.
2522 mState.mTextures->invalidateTextureComplenessCache();
2523 for (auto &zeroTexture : mZeroTextures)
2524 {
2525 zeroTexture.second->invalidateCompletenessCache();
2526 }
2527
2528 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002529}
2530
2531size_t Context::getRequestableExtensionStringCount() const
2532{
2533 return mRequestableExtensionStrings.size();
2534}
2535
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002536void Context::beginTransformFeedback(GLenum primitiveMode)
2537{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002538 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002539 ASSERT(transformFeedback != nullptr);
2540 ASSERT(!transformFeedback->isPaused());
2541
Jamie Madill6c1f6712017-02-14 19:08:04 -05002542 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002543}
2544
2545bool Context::hasActiveTransformFeedback(GLuint program) const
2546{
2547 for (auto pair : mTransformFeedbackMap)
2548 {
2549 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2550 {
2551 return true;
2552 }
2553 }
2554 return false;
2555}
2556
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002557void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002558{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002559 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002560
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002561 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002562
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002563 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002564
Geoff Langeb66a6e2016-10-31 13:06:12 -04002565 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002566 {
2567 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002568 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002569 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002570 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002571 mExtensions.multiview = false;
2572 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002573 }
2574
Geoff Langeb66a6e2016-10-31 13:06:12 -04002575 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002576 {
2577 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002578 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002579 }
2580
Jamie Madill00ed7a12016-05-19 13:13:38 -04002581 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002582 mExtensions.bindUniformLocation = true;
2583 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002584 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002585 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002586 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002587
2588 // Enable the no error extension if the context was created with the flag.
2589 mExtensions.noError = mSkipValidation;
2590
Corentin Wallezccab69d2017-01-27 16:57:15 -05002591 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002592 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002593
Geoff Lang70d0f492015-12-10 17:45:46 -05002594 // Explicitly enable GL_KHR_debug
2595 mExtensions.debug = true;
2596 mExtensions.maxDebugMessageLength = 1024;
2597 mExtensions.maxDebugLoggedMessages = 1024;
2598 mExtensions.maxDebugGroupStackDepth = 1024;
2599 mExtensions.maxLabelLength = 1024;
2600
Geoff Langff5b2d52016-09-07 11:32:23 -04002601 // Explicitly enable GL_ANGLE_robust_client_memory
2602 mExtensions.robustClientMemory = true;
2603
Jamie Madille08a1d32017-03-07 17:24:06 -05002604 // Determine robust resource init availability from EGL.
2605 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002606 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002607
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08002608 // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend
2609 // supports it.
2610 mExtensions.robustBufferAccessBehavior =
2611 mRobustAccess && mExtensions.robustBufferAccessBehavior;
2612
Jamie Madillc43be722017-07-13 16:22:14 -04002613 // Enable the cache control query unconditionally.
2614 mExtensions.programCacheControl = true;
2615
Geoff Lang301d1612014-07-09 10:34:37 -04002616 // Apply implementation limits
2617 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002618 mCaps.maxVertexAttribBindings =
2619 getClientVersion() < ES_3_1
2620 ? mCaps.maxVertexAttributes
2621 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2622
Jamie Madill231c7f52017-04-26 13:45:37 -04002623 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2624 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2625 mCaps.maxVertexOutputComponents =
2626 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002627
Jamie Madill231c7f52017-04-26 13:45:37 -04002628 mCaps.maxFragmentInputComponents =
2629 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002630
Geoff Langc287ea62016-09-16 14:46:51 -04002631 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002632 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002633 for (const auto &extensionInfo : GetExtensionInfoMap())
2634 {
2635 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002636 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002637 {
2638 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2639 }
2640 }
2641
2642 // Generate texture caps
2643 updateCaps();
2644}
2645
2646void Context::updateCaps()
2647{
Geoff Lang900013c2014-07-07 11:32:19 -04002648 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002649 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002650
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002651 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002652 {
Geoff Langca271392017-04-05 12:30:00 -04002653 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002654 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002655
Geoff Langca271392017-04-05 12:30:00 -04002656 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002657
Geoff Lang0d8b7242015-09-09 14:56:53 -04002658 // Update the format caps based on the client version and extensions.
2659 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2660 // ES3.
2661 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002662 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002663 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002664 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002665 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002666 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002667
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002668 // OpenGL ES does not support multisampling with non-rendererable formats
2669 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002670 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002671 (getClientVersion() < ES_3_1 &&
2672 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002673 {
Geoff Langd87878e2014-09-19 15:42:59 -04002674 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002675 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002676 else
2677 {
2678 // We may have limited the max samples for some required renderbuffer formats due to
2679 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2680 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2681
2682 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2683 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2684 // exception of signed and unsigned integer formats."
2685 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2686 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2687 {
2688 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2689 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2690 }
2691
2692 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2693 if (getClientVersion() >= ES_3_1)
2694 {
2695 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2696 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2697 // the exception that the signed and unsigned integer formats are required only to
2698 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2699 // multisamples, which must be at least one."
2700 if (formatInfo.componentType == GL_INT ||
2701 formatInfo.componentType == GL_UNSIGNED_INT)
2702 {
2703 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2704 }
2705
2706 // GLES 3.1 section 19.3.1.
2707 if (formatCaps.texturable)
2708 {
2709 if (formatInfo.depthBits > 0)
2710 {
2711 mCaps.maxDepthTextureSamples =
2712 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2713 }
2714 else if (formatInfo.redBits > 0)
2715 {
2716 mCaps.maxColorTextureSamples =
2717 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2718 }
2719 }
2720 }
2721 }
Geoff Langd87878e2014-09-19 15:42:59 -04002722
2723 if (formatCaps.texturable && formatInfo.compressed)
2724 {
Geoff Langca271392017-04-05 12:30:00 -04002725 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002726 }
2727
Geoff Langca271392017-04-05 12:30:00 -04002728 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002729 }
Jamie Madill32447362017-06-28 14:53:52 -04002730
2731 // If program binary is disabled, blank out the memory cache pointer.
2732 if (!mImplementation->getNativeExtensions().getProgramBinary)
2733 {
2734 mMemoryProgramCache = nullptr;
2735 }
Geoff Lang493daf52014-07-03 13:38:44 -04002736}
2737
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002738void Context::initWorkarounds()
2739{
Jamie Madill761b02c2017-06-23 16:27:06 -04002740 // Apply back-end workarounds.
2741 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2742
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002743 // Lose the context upon out of memory error if the application is
2744 // expecting to watch for those events.
2745 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2746}
2747
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002748Error Context::prepareForDraw(GLenum drawMode)
Jamie Madillb6664922017-07-25 12:55:04 -04002749{
2750 syncRendererState();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002751
2752 InfoLog infoLog;
2753 Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
2754 mMemoryProgramCache, drawMode);
Jamie Madilla836b462017-08-16 14:58:35 -04002755 if (err.isError() || infoLog.getLength() > 0)
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002756 {
2757 WARN() << "Dynamic recompilation error log: " << infoLog.str();
2758 }
2759 return err;
Jamie Madillb6664922017-07-25 12:55:04 -04002760}
2761
Jamie Madill1b94d432015-08-07 13:23:23 -04002762void Context::syncRendererState()
2763{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002764 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002765 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002766 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002767 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002768}
2769
Jamie Madillad9f24e2016-02-12 09:27:24 -05002770void Context::syncRendererState(const State::DirtyBits &bitMask,
2771 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002772{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002773 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002774 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002775 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002776 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002777}
Jamie Madillc29968b2016-01-20 11:17:23 -05002778
2779void Context::blitFramebuffer(GLint srcX0,
2780 GLint srcY0,
2781 GLint srcX1,
2782 GLint srcY1,
2783 GLint dstX0,
2784 GLint dstY0,
2785 GLint dstX1,
2786 GLint dstY1,
2787 GLbitfield mask,
2788 GLenum filter)
2789{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002790 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002791 ASSERT(drawFramebuffer);
2792
2793 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2794 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2795
Jamie Madillad9f24e2016-02-12 09:27:24 -05002796 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002797
Jamie Madillc564c072017-06-01 12:45:42 -04002798 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002799}
Jamie Madillc29968b2016-01-20 11:17:23 -05002800
2801void Context::clear(GLbitfield mask)
2802{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002803 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002804 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002805}
2806
2807void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2808{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002809 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002810 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002811}
2812
2813void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2814{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002815 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002816 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002817}
2818
2819void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2820{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002821 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002822 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002823}
2824
2825void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2826{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002827 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002828 ASSERT(framebufferObject);
2829
2830 // If a buffer is not present, the clear has no effect
2831 if (framebufferObject->getDepthbuffer() == nullptr &&
2832 framebufferObject->getStencilbuffer() == nullptr)
2833 {
2834 return;
2835 }
2836
Jamie Madillad9f24e2016-02-12 09:27:24 -05002837 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002838 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002839}
2840
2841void Context::readPixels(GLint x,
2842 GLint y,
2843 GLsizei width,
2844 GLsizei height,
2845 GLenum format,
2846 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002847 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002848{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002849 if (width == 0 || height == 0)
2850 {
2851 return;
2852 }
2853
Jamie Madillad9f24e2016-02-12 09:27:24 -05002854 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002855
Jamie Madillb6664922017-07-25 12:55:04 -04002856 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2857 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002858
2859 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002860 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002861}
2862
2863void Context::copyTexImage2D(GLenum target,
2864 GLint level,
2865 GLenum internalformat,
2866 GLint x,
2867 GLint y,
2868 GLsizei width,
2869 GLsizei height,
2870 GLint border)
2871{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002872 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002873 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002874
Jamie Madillc29968b2016-01-20 11:17:23 -05002875 Rectangle sourceArea(x, y, width, height);
2876
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002877 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002878 Texture *texture =
2879 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002880 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002881}
2882
2883void Context::copyTexSubImage2D(GLenum target,
2884 GLint level,
2885 GLint xoffset,
2886 GLint yoffset,
2887 GLint x,
2888 GLint y,
2889 GLsizei width,
2890 GLsizei height)
2891{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002892 if (width == 0 || height == 0)
2893 {
2894 return;
2895 }
2896
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002897 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002898 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002899
Jamie Madillc29968b2016-01-20 11:17:23 -05002900 Offset destOffset(xoffset, yoffset, 0);
2901 Rectangle sourceArea(x, y, width, height);
2902
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002903 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002904 Texture *texture =
2905 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002906 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002907}
2908
2909void Context::copyTexSubImage3D(GLenum target,
2910 GLint level,
2911 GLint xoffset,
2912 GLint yoffset,
2913 GLint zoffset,
2914 GLint x,
2915 GLint y,
2916 GLsizei width,
2917 GLsizei height)
2918{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002919 if (width == 0 || height == 0)
2920 {
2921 return;
2922 }
2923
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002924 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002925 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002926
Jamie Madillc29968b2016-01-20 11:17:23 -05002927 Offset destOffset(xoffset, yoffset, zoffset);
2928 Rectangle sourceArea(x, y, width, height);
2929
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002930 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002931 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002932 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002933}
2934
2935void Context::framebufferTexture2D(GLenum target,
2936 GLenum attachment,
2937 GLenum textarget,
2938 GLuint texture,
2939 GLint level)
2940{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002941 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002942 ASSERT(framebuffer);
2943
2944 if (texture != 0)
2945 {
2946 Texture *textureObj = getTexture(texture);
2947
2948 ImageIndex index = ImageIndex::MakeInvalid();
2949
2950 if (textarget == GL_TEXTURE_2D)
2951 {
2952 index = ImageIndex::Make2D(level);
2953 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002954 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
2955 {
2956 index = ImageIndex::MakeRectangle(level);
2957 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002958 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2959 {
2960 ASSERT(level == 0);
2961 index = ImageIndex::Make2DMultisample();
2962 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002963 else
2964 {
2965 ASSERT(IsCubeMapTextureTarget(textarget));
2966 index = ImageIndex::MakeCube(textarget, level);
2967 }
2968
Jamie Madilla02315b2017-02-23 14:14:47 -05002969 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002970 }
2971 else
2972 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002973 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002974 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002975
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002976 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002977}
2978
2979void Context::framebufferRenderbuffer(GLenum target,
2980 GLenum attachment,
2981 GLenum renderbuffertarget,
2982 GLuint renderbuffer)
2983{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002984 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002985 ASSERT(framebuffer);
2986
2987 if (renderbuffer != 0)
2988 {
2989 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002990
2991 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002992 renderbufferObject);
2993 }
2994 else
2995 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002996 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002997 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002998
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002999 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003000}
3001
3002void Context::framebufferTextureLayer(GLenum target,
3003 GLenum attachment,
3004 GLuint texture,
3005 GLint level,
3006 GLint layer)
3007{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003008 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003009 ASSERT(framebuffer);
3010
3011 if (texture != 0)
3012 {
3013 Texture *textureObject = getTexture(texture);
3014
3015 ImageIndex index = ImageIndex::MakeInvalid();
3016
3017 if (textureObject->getTarget() == GL_TEXTURE_3D)
3018 {
3019 index = ImageIndex::Make3D(level, layer);
3020 }
3021 else
3022 {
3023 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3024 index = ImageIndex::Make2DArray(level, layer);
3025 }
3026
Jamie Madilla02315b2017-02-23 14:14:47 -05003027 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003028 }
3029 else
3030 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003031 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003032 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003033
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003034 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003035}
3036
Martin Radev137032d2017-07-13 10:11:12 +03003037void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3038 GLenum attachment,
3039 GLuint texture,
3040 GLint level,
3041 GLint baseViewIndex,
3042 GLsizei numViews)
3043{
Martin Radev82ef7742017-08-08 17:44:58 +03003044 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3045 ASSERT(framebuffer);
3046
3047 if (texture != 0)
3048 {
3049 Texture *textureObj = getTexture(texture);
3050
Martin Radev18b75ba2017-08-15 15:50:40 +03003051 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003052 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3053 numViews, baseViewIndex);
3054 }
3055 else
3056 {
3057 framebuffer->resetAttachment(this, attachment);
3058 }
3059
3060 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003061}
3062
3063void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3064 GLenum attachment,
3065 GLuint texture,
3066 GLint level,
3067 GLsizei numViews,
3068 const GLint *viewportOffsets)
3069{
Martin Radev5dae57b2017-07-14 16:15:55 +03003070 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3071 ASSERT(framebuffer);
3072
3073 if (texture != 0)
3074 {
3075 Texture *textureObj = getTexture(texture);
3076
3077 ImageIndex index = ImageIndex::Make2D(level);
3078 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3079 textureObj, numViews, viewportOffsets);
3080 }
3081 else
3082 {
3083 framebuffer->resetAttachment(this, attachment);
3084 }
3085
3086 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003087}
3088
Jamie Madillc29968b2016-01-20 11:17:23 -05003089void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3090{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003091 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003092 ASSERT(framebuffer);
3093 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003094 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003095}
3096
3097void Context::readBuffer(GLenum mode)
3098{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003099 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003100 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003101 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003102}
3103
3104void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3105{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003106 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003107 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003108
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003109 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003110 ASSERT(framebuffer);
3111
3112 // The specification isn't clear what should be done when the framebuffer isn't complete.
3113 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003114 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003115}
3116
3117void Context::invalidateFramebuffer(GLenum target,
3118 GLsizei numAttachments,
3119 const GLenum *attachments)
3120{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003121 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003122 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003123
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003124 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003125 ASSERT(framebuffer);
3126
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003127 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003128 {
Jamie Madill437fa652016-05-03 15:13:24 -04003129 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003130 }
Jamie Madill437fa652016-05-03 15:13:24 -04003131
Jamie Madill4928b7c2017-06-20 12:57:39 -04003132 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003133}
3134
3135void Context::invalidateSubFramebuffer(GLenum target,
3136 GLsizei numAttachments,
3137 const GLenum *attachments,
3138 GLint x,
3139 GLint y,
3140 GLsizei width,
3141 GLsizei height)
3142{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003143 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003144 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003145
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003146 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003147 ASSERT(framebuffer);
3148
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003149 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003150 {
Jamie Madill437fa652016-05-03 15:13:24 -04003151 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003152 }
Jamie Madill437fa652016-05-03 15:13:24 -04003153
3154 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003155 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003156}
3157
Jamie Madill73a84962016-02-12 09:27:23 -05003158void Context::texImage2D(GLenum target,
3159 GLint level,
3160 GLint internalformat,
3161 GLsizei width,
3162 GLsizei height,
3163 GLint border,
3164 GLenum format,
3165 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003166 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003167{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003168 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003169
3170 Extents size(width, height, 1);
3171 Texture *texture =
3172 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003173 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3174 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003175}
3176
3177void Context::texImage3D(GLenum target,
3178 GLint level,
3179 GLint internalformat,
3180 GLsizei width,
3181 GLsizei height,
3182 GLsizei depth,
3183 GLint border,
3184 GLenum format,
3185 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003186 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003187{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003188 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003189
3190 Extents size(width, height, depth);
3191 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003192 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3193 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003194}
3195
3196void Context::texSubImage2D(GLenum target,
3197 GLint level,
3198 GLint xoffset,
3199 GLint yoffset,
3200 GLsizei width,
3201 GLsizei height,
3202 GLenum format,
3203 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003204 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003205{
3206 // Zero sized uploads are valid but no-ops
3207 if (width == 0 || height == 0)
3208 {
3209 return;
3210 }
3211
Jamie Madillad9f24e2016-02-12 09:27:24 -05003212 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003213
3214 Box area(xoffset, yoffset, 0, width, height, 1);
3215 Texture *texture =
3216 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003217 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3218 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003219}
3220
3221void Context::texSubImage3D(GLenum target,
3222 GLint level,
3223 GLint xoffset,
3224 GLint yoffset,
3225 GLint zoffset,
3226 GLsizei width,
3227 GLsizei height,
3228 GLsizei depth,
3229 GLenum format,
3230 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003231 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003232{
3233 // Zero sized uploads are valid but no-ops
3234 if (width == 0 || height == 0 || depth == 0)
3235 {
3236 return;
3237 }
3238
Jamie Madillad9f24e2016-02-12 09:27:24 -05003239 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003240
3241 Box area(xoffset, yoffset, zoffset, width, height, depth);
3242 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003243 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3244 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003245}
3246
3247void Context::compressedTexImage2D(GLenum target,
3248 GLint level,
3249 GLenum internalformat,
3250 GLsizei width,
3251 GLsizei height,
3252 GLint border,
3253 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003254 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003255{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003256 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003257
3258 Extents size(width, height, 1);
3259 Texture *texture =
3260 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003261 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003262 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003263 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003264}
3265
3266void Context::compressedTexImage3D(GLenum target,
3267 GLint level,
3268 GLenum internalformat,
3269 GLsizei width,
3270 GLsizei height,
3271 GLsizei depth,
3272 GLint border,
3273 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003274 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003275{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003276 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003277
3278 Extents size(width, height, depth);
3279 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003280 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003281 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003282 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003283}
3284
3285void Context::compressedTexSubImage2D(GLenum target,
3286 GLint level,
3287 GLint xoffset,
3288 GLint yoffset,
3289 GLsizei width,
3290 GLsizei height,
3291 GLenum format,
3292 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003293 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003294{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003295 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003296
3297 Box area(xoffset, yoffset, 0, width, height, 1);
3298 Texture *texture =
3299 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003300 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003301 format, imageSize,
3302 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003303}
3304
3305void Context::compressedTexSubImage3D(GLenum target,
3306 GLint level,
3307 GLint xoffset,
3308 GLint yoffset,
3309 GLint zoffset,
3310 GLsizei width,
3311 GLsizei height,
3312 GLsizei depth,
3313 GLenum format,
3314 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003315 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003316{
3317 // Zero sized uploads are valid but no-ops
3318 if (width == 0 || height == 0)
3319 {
3320 return;
3321 }
3322
Jamie Madillad9f24e2016-02-12 09:27:24 -05003323 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003324
3325 Box area(xoffset, yoffset, zoffset, width, height, depth);
3326 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003327 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003328 format, imageSize,
3329 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003330}
3331
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003332void Context::generateMipmap(GLenum target)
3333{
3334 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003335 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003336}
3337
Geoff Lang97073d12016-04-20 10:42:34 -07003338void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003339 GLint sourceLevel,
3340 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003341 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003342 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003343 GLint internalFormat,
3344 GLenum destType,
3345 GLboolean unpackFlipY,
3346 GLboolean unpackPremultiplyAlpha,
3347 GLboolean unpackUnmultiplyAlpha)
3348{
3349 syncStateForTexImage();
3350
3351 gl::Texture *sourceTexture = getTexture(sourceId);
3352 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003353 handleError(destTexture->copyTexture(
3354 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3355 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003356}
3357
3358void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003359 GLint sourceLevel,
3360 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003361 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003362 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003363 GLint xoffset,
3364 GLint yoffset,
3365 GLint x,
3366 GLint y,
3367 GLsizei width,
3368 GLsizei height,
3369 GLboolean unpackFlipY,
3370 GLboolean unpackPremultiplyAlpha,
3371 GLboolean unpackUnmultiplyAlpha)
3372{
3373 // Zero sized copies are valid but no-ops
3374 if (width == 0 || height == 0)
3375 {
3376 return;
3377 }
3378
3379 syncStateForTexImage();
3380
3381 gl::Texture *sourceTexture = getTexture(sourceId);
3382 gl::Texture *destTexture = getTexture(destId);
3383 Offset offset(xoffset, yoffset, 0);
3384 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003385 handleError(destTexture->copySubTexture(
3386 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3387 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003388}
3389
Geoff Lang47110bf2016-04-20 11:13:22 -07003390void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3391{
3392 syncStateForTexImage();
3393
3394 gl::Texture *sourceTexture = getTexture(sourceId);
3395 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003396 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003397}
3398
Geoff Lang496c02d2016-10-20 11:38:11 -07003399void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003400{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003401 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003402 ASSERT(buffer);
3403
Geoff Lang496c02d2016-10-20 11:38:11 -07003404 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003405}
3406
Jamie Madill876429b2017-04-20 15:46:24 -04003407void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003408{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003409 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003410 ASSERT(buffer);
3411
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003412 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003413 if (error.isError())
3414 {
Jamie Madill437fa652016-05-03 15:13:24 -04003415 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003416 return nullptr;
3417 }
3418
3419 return buffer->getMapPointer();
3420}
3421
3422GLboolean Context::unmapBuffer(GLenum target)
3423{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003425 ASSERT(buffer);
3426
3427 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003428 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003429 if (error.isError())
3430 {
Jamie Madill437fa652016-05-03 15:13:24 -04003431 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003432 return GL_FALSE;
3433 }
3434
3435 return result;
3436}
3437
Jamie Madill876429b2017-04-20 15:46:24 -04003438void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003439{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003440 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003441 ASSERT(buffer);
3442
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003443 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003444 if (error.isError())
3445 {
Jamie Madill437fa652016-05-03 15:13:24 -04003446 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003447 return nullptr;
3448 }
3449
3450 return buffer->getMapPointer();
3451}
3452
3453void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3454{
3455 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3456}
3457
Jamie Madillad9f24e2016-02-12 09:27:24 -05003458void Context::syncStateForReadPixels()
3459{
3460 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3461}
3462
3463void Context::syncStateForTexImage()
3464{
3465 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3466}
3467
3468void Context::syncStateForClear()
3469{
3470 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3471}
3472
3473void Context::syncStateForBlit()
3474{
3475 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3476}
3477
Jamie Madillc20ab272016-06-09 07:20:46 -07003478void Context::activeTexture(GLenum texture)
3479{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003480 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003481}
3482
Jamie Madill876429b2017-04-20 15:46:24 -04003483void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003484{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003485 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003486}
3487
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003488void Context::blendEquation(GLenum mode)
3489{
3490 mGLState.setBlendEquation(mode, mode);
3491}
3492
Jamie Madillc20ab272016-06-09 07:20:46 -07003493void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3494{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003495 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003496}
3497
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003498void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3499{
3500 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3501}
3502
Jamie Madillc20ab272016-06-09 07:20:46 -07003503void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3504{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003505 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003506}
3507
Jamie Madill876429b2017-04-20 15:46:24 -04003508void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003509{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003510 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003511}
3512
Jamie Madill876429b2017-04-20 15:46:24 -04003513void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003514{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003515 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003516}
3517
3518void Context::clearStencil(GLint s)
3519{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521}
3522
3523void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3524{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
3528void Context::cullFace(GLenum mode)
3529{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003530 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003531}
3532
3533void Context::depthFunc(GLenum func)
3534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003535 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003536}
3537
3538void Context::depthMask(GLboolean flag)
3539{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003540 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003541}
3542
Jamie Madill876429b2017-04-20 15:46:24 -04003543void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003544{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003545 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003546}
3547
3548void Context::disable(GLenum cap)
3549{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003551}
3552
3553void Context::disableVertexAttribArray(GLuint index)
3554{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003555 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003556}
3557
3558void Context::enable(GLenum cap)
3559{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003560 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003561}
3562
3563void Context::enableVertexAttribArray(GLuint index)
3564{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003565 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003566}
3567
3568void Context::frontFace(GLenum mode)
3569{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003570 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003571}
3572
3573void Context::hint(GLenum target, GLenum mode)
3574{
3575 switch (target)
3576 {
3577 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003578 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003579 break;
3580
3581 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003582 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003583 break;
3584
3585 default:
3586 UNREACHABLE();
3587 return;
3588 }
3589}
3590
3591void Context::lineWidth(GLfloat width)
3592{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003593 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003594}
3595
3596void Context::pixelStorei(GLenum pname, GLint param)
3597{
3598 switch (pname)
3599 {
3600 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003601 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003602 break;
3603
3604 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003605 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003606 break;
3607
3608 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003609 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003610 break;
3611
3612 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003613 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003614 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003615 break;
3616
3617 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003618 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003619 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003620 break;
3621
3622 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003623 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003624 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003625 break;
3626
3627 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003628 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003629 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003630 break;
3631
3632 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003633 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003634 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003635 break;
3636
3637 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003638 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003639 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003640 break;
3641
3642 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003643 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003644 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003645 break;
3646
3647 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003648 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003649 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003650 break;
3651
3652 default:
3653 UNREACHABLE();
3654 return;
3655 }
3656}
3657
3658void Context::polygonOffset(GLfloat factor, GLfloat units)
3659{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003660 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003661}
3662
Jamie Madill876429b2017-04-20 15:46:24 -04003663void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003664{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003665 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003666}
3667
3668void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3669{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003670 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003671}
3672
3673void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3674{
3675 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3676 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003677 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003678 }
3679
3680 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3681 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003682 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003683 }
3684}
3685
3686void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3687{
3688 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3689 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003690 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003691 }
3692
3693 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3694 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003695 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003696 }
3697}
3698
3699void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3700{
3701 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3702 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003703 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003704 }
3705
3706 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3707 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003708 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003709 }
3710}
3711
3712void Context::vertexAttrib1f(GLuint index, GLfloat x)
3713{
3714 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003715 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003716}
3717
3718void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3719{
3720 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003721 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003722}
3723
3724void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3725{
3726 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003727 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003728}
3729
3730void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3731{
3732 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003733 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003734}
3735
3736void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3737{
3738 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003739 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003740}
3741
3742void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3743{
3744 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003745 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003746}
3747
3748void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3749{
3750 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003751 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003752}
3753
3754void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3755{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003756 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003757}
3758
3759void Context::vertexAttribPointer(GLuint index,
3760 GLint size,
3761 GLenum type,
3762 GLboolean normalized,
3763 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003764 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003765{
Shaodde78e82017-05-22 14:13:27 +08003766 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3767 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003768}
3769
Shao80957d92017-02-20 21:25:59 +08003770void Context::vertexAttribFormat(GLuint attribIndex,
3771 GLint size,
3772 GLenum type,
3773 GLboolean normalized,
3774 GLuint relativeOffset)
3775{
3776 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3777 relativeOffset);
3778}
3779
3780void Context::vertexAttribIFormat(GLuint attribIndex,
3781 GLint size,
3782 GLenum type,
3783 GLuint relativeOffset)
3784{
3785 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3786}
3787
3788void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3789{
Shaodde78e82017-05-22 14:13:27 +08003790 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003791}
3792
3793void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3794{
3795 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3796}
3797
Jamie Madillc20ab272016-06-09 07:20:46 -07003798void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3799{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003800 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003801}
3802
3803void Context::vertexAttribIPointer(GLuint index,
3804 GLint size,
3805 GLenum type,
3806 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003807 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003808{
Shaodde78e82017-05-22 14:13:27 +08003809 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3810 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003811}
3812
3813void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3814{
3815 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003816 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003817}
3818
3819void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3820{
3821 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003822 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003823}
3824
3825void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3826{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003827 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003828}
3829
3830void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3831{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003832 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003833}
3834
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003835void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3836{
3837 const VertexAttribCurrentValueData &currentValues =
3838 getGLState().getVertexAttribCurrentValue(index);
3839 const VertexArray *vao = getGLState().getVertexArray();
3840 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3841 currentValues, pname, params);
3842}
3843
3844void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3845{
3846 const VertexAttribCurrentValueData &currentValues =
3847 getGLState().getVertexAttribCurrentValue(index);
3848 const VertexArray *vao = getGLState().getVertexArray();
3849 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3850 currentValues, pname, params);
3851}
3852
3853void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3854{
3855 const VertexAttribCurrentValueData &currentValues =
3856 getGLState().getVertexAttribCurrentValue(index);
3857 const VertexArray *vao = getGLState().getVertexArray();
3858 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3859 currentValues, pname, params);
3860}
3861
3862void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3863{
3864 const VertexAttribCurrentValueData &currentValues =
3865 getGLState().getVertexAttribCurrentValue(index);
3866 const VertexArray *vao = getGLState().getVertexArray();
3867 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3868 currentValues, pname, params);
3869}
3870
Jamie Madill876429b2017-04-20 15:46:24 -04003871void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003872{
3873 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3874 QueryVertexAttribPointerv(attrib, pname, pointer);
3875}
3876
Jamie Madillc20ab272016-06-09 07:20:46 -07003877void Context::debugMessageControl(GLenum source,
3878 GLenum type,
3879 GLenum severity,
3880 GLsizei count,
3881 const GLuint *ids,
3882 GLboolean enabled)
3883{
3884 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003885 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3886 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003887}
3888
3889void Context::debugMessageInsert(GLenum source,
3890 GLenum type,
3891 GLuint id,
3892 GLenum severity,
3893 GLsizei length,
3894 const GLchar *buf)
3895{
3896 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003897 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003898}
3899
3900void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3901{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003902 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003903}
3904
3905GLuint Context::getDebugMessageLog(GLuint count,
3906 GLsizei bufSize,
3907 GLenum *sources,
3908 GLenum *types,
3909 GLuint *ids,
3910 GLenum *severities,
3911 GLsizei *lengths,
3912 GLchar *messageLog)
3913{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003914 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3915 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003916}
3917
3918void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3919{
3920 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003921 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003922}
3923
3924void Context::popDebugGroup()
3925{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003926 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003927}
3928
Jamie Madill876429b2017-04-20 15:46:24 -04003929void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003930{
3931 Buffer *buffer = mGLState.getTargetBuffer(target);
3932 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003933 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003934}
3935
Jamie Madill876429b2017-04-20 15:46:24 -04003936void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003937{
3938 if (data == nullptr)
3939 {
3940 return;
3941 }
3942
3943 Buffer *buffer = mGLState.getTargetBuffer(target);
3944 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003945 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003946}
3947
Jamie Madillef300b12016-10-07 15:12:09 -04003948void Context::attachShader(GLuint program, GLuint shader)
3949{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003950 auto programObject = mState.mShaderPrograms->getProgram(program);
3951 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003952 ASSERT(programObject && shaderObject);
3953 programObject->attachShader(shaderObject);
3954}
3955
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003956const Workarounds &Context::getWorkarounds() const
3957{
3958 return mWorkarounds;
3959}
3960
Jamie Madillb0817d12016-11-01 15:48:31 -04003961void Context::copyBufferSubData(GLenum readTarget,
3962 GLenum writeTarget,
3963 GLintptr readOffset,
3964 GLintptr writeOffset,
3965 GLsizeiptr size)
3966{
3967 // if size is zero, the copy is a successful no-op
3968 if (size == 0)
3969 {
3970 return;
3971 }
3972
3973 // TODO(jmadill): cache these.
3974 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3975 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3976
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003977 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003978}
3979
Jamie Madill01a80ee2016-11-07 12:06:18 -05003980void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3981{
3982 Program *programObject = getProgram(program);
3983 // TODO(jmadill): Re-use this from the validation if possible.
3984 ASSERT(programObject);
3985 programObject->bindAttributeLocation(index, name);
3986}
3987
3988void Context::bindBuffer(GLenum target, GLuint buffer)
3989{
3990 switch (target)
3991 {
3992 case GL_ARRAY_BUFFER:
3993 bindArrayBuffer(buffer);
3994 break;
3995 case GL_ELEMENT_ARRAY_BUFFER:
3996 bindElementArrayBuffer(buffer);
3997 break;
3998 case GL_COPY_READ_BUFFER:
3999 bindCopyReadBuffer(buffer);
4000 break;
4001 case GL_COPY_WRITE_BUFFER:
4002 bindCopyWriteBuffer(buffer);
4003 break;
4004 case GL_PIXEL_PACK_BUFFER:
4005 bindPixelPackBuffer(buffer);
4006 break;
4007 case GL_PIXEL_UNPACK_BUFFER:
4008 bindPixelUnpackBuffer(buffer);
4009 break;
4010 case GL_UNIFORM_BUFFER:
4011 bindGenericUniformBuffer(buffer);
4012 break;
4013 case GL_TRANSFORM_FEEDBACK_BUFFER:
4014 bindGenericTransformFeedbackBuffer(buffer);
4015 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004016 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004017 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004018 break;
4019 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004020 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004021 break;
4022 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004023 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004024 break;
4025 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004026 if (buffer != 0)
4027 {
4028 // Binding buffers to this binding point is not implemented yet.
4029 UNIMPLEMENTED();
4030 }
Geoff Lang3b573612016-10-31 14:08:10 -04004031 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004032
4033 default:
4034 UNREACHABLE();
4035 break;
4036 }
4037}
4038
Jiajia Qin6eafb042016-12-27 17:04:07 +08004039void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4040{
4041 bindBufferRange(target, index, buffer, 0, 0);
4042}
4043
4044void Context::bindBufferRange(GLenum target,
4045 GLuint index,
4046 GLuint buffer,
4047 GLintptr offset,
4048 GLsizeiptr size)
4049{
4050 switch (target)
4051 {
4052 case GL_TRANSFORM_FEEDBACK_BUFFER:
4053 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4054 bindGenericTransformFeedbackBuffer(buffer);
4055 break;
4056 case GL_UNIFORM_BUFFER:
4057 bindIndexedUniformBuffer(buffer, index, offset, size);
4058 bindGenericUniformBuffer(buffer);
4059 break;
4060 case GL_ATOMIC_COUNTER_BUFFER:
4061 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4062 bindGenericAtomicCounterBuffer(buffer);
4063 break;
4064 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004065 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4066 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004067 break;
4068 default:
4069 UNREACHABLE();
4070 break;
4071 }
4072}
4073
Jamie Madill01a80ee2016-11-07 12:06:18 -05004074void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4075{
4076 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4077 {
4078 bindReadFramebuffer(framebuffer);
4079 }
4080
4081 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4082 {
4083 bindDrawFramebuffer(framebuffer);
4084 }
4085}
4086
4087void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4088{
4089 ASSERT(target == GL_RENDERBUFFER);
4090 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004091 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004092 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004093}
4094
JiangYizhoubddc46b2016-12-09 09:50:51 +08004095void Context::texStorage2DMultisample(GLenum target,
4096 GLsizei samples,
4097 GLenum internalformat,
4098 GLsizei width,
4099 GLsizei height,
4100 GLboolean fixedsamplelocations)
4101{
4102 Extents size(width, height, 1);
4103 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004104 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004105 fixedsamplelocations));
4106}
4107
4108void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4109{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004110 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004111 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4112
4113 switch (pname)
4114 {
4115 case GL_SAMPLE_POSITION:
4116 handleError(framebuffer->getSamplePosition(index, val));
4117 break;
4118 default:
4119 UNREACHABLE();
4120 }
4121}
4122
Jamie Madille8fb6402017-02-14 17:56:40 -05004123void Context::renderbufferStorage(GLenum target,
4124 GLenum internalformat,
4125 GLsizei width,
4126 GLsizei height)
4127{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004128 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4129 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4130
Jamie Madille8fb6402017-02-14 17:56:40 -05004131 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004132 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004133}
4134
4135void Context::renderbufferStorageMultisample(GLenum target,
4136 GLsizei samples,
4137 GLenum internalformat,
4138 GLsizei width,
4139 GLsizei height)
4140{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004141 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4142 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004143
4144 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004145 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004146 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004147}
4148
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004149void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4150{
Jamie Madill70b5bb02017-08-28 13:32:37 -04004151 const Sync *syncObject = getSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004152 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004153}
4154
JiangYizhoue18e6392017-02-20 10:32:23 +08004155void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4156{
4157 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4158 QueryFramebufferParameteriv(framebuffer, pname, params);
4159}
4160
4161void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4162{
4163 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4164 SetFramebufferParameteri(framebuffer, pname, param);
4165}
4166
Jamie Madillb3f26b92017-07-19 15:07:41 -04004167Error Context::getScratchBuffer(size_t requstedSizeBytes,
4168 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004169{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004170 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4171 {
4172 return OutOfMemory() << "Failed to allocate internal buffer.";
4173 }
4174 return NoError();
4175}
4176
4177Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4178 angle::MemoryBuffer **zeroBufferOut) const
4179{
4180 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004182 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004183 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004184 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004185}
4186
Xinghua Cao2b396592017-03-29 15:36:04 +08004187void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4188{
4189 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4190 {
4191 return;
4192 }
4193
Jamie Madillfe548342017-06-19 11:13:24 -04004194 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004195}
4196
JiangYizhou165361c2017-06-07 14:56:57 +08004197void Context::texStorage2D(GLenum target,
4198 GLsizei levels,
4199 GLenum internalFormat,
4200 GLsizei width,
4201 GLsizei height)
4202{
4203 Extents size(width, height, 1);
4204 Texture *texture = getTargetTexture(target);
4205 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4206}
4207
4208void Context::texStorage3D(GLenum target,
4209 GLsizei levels,
4210 GLenum internalFormat,
4211 GLsizei width,
4212 GLsizei height,
4213 GLsizei depth)
4214{
4215 Extents size(width, height, depth);
4216 Texture *texture = getTargetTexture(target);
4217 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4218}
4219
Jamie Madillc1d770e2017-04-13 17:31:24 -04004220GLenum Context::checkFramebufferStatus(GLenum target)
4221{
4222 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4223 ASSERT(framebuffer);
4224
4225 return framebuffer->checkStatus(this);
4226}
4227
4228void Context::compileShader(GLuint shader)
4229{
4230 Shader *shaderObject = GetValidShader(this, shader);
4231 if (!shaderObject)
4232 {
4233 return;
4234 }
4235 shaderObject->compile(this);
4236}
4237
4238void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4239{
4240 for (int i = 0; i < n; i++)
4241 {
4242 deleteBuffer(buffers[i]);
4243 }
4244}
4245
4246void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4247{
4248 for (int i = 0; i < n; i++)
4249 {
4250 if (framebuffers[i] != 0)
4251 {
4252 deleteFramebuffer(framebuffers[i]);
4253 }
4254 }
4255}
4256
4257void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4258{
4259 for (int i = 0; i < n; i++)
4260 {
4261 deleteRenderbuffer(renderbuffers[i]);
4262 }
4263}
4264
4265void Context::deleteTextures(GLsizei n, const GLuint *textures)
4266{
4267 for (int i = 0; i < n; i++)
4268 {
4269 if (textures[i] != 0)
4270 {
4271 deleteTexture(textures[i]);
4272 }
4273 }
4274}
4275
4276void Context::detachShader(GLuint program, GLuint shader)
4277{
4278 Program *programObject = getProgram(program);
4279 ASSERT(programObject);
4280
4281 Shader *shaderObject = getShader(shader);
4282 ASSERT(shaderObject);
4283
4284 programObject->detachShader(this, shaderObject);
4285}
4286
4287void Context::genBuffers(GLsizei n, GLuint *buffers)
4288{
4289 for (int i = 0; i < n; i++)
4290 {
4291 buffers[i] = createBuffer();
4292 }
4293}
4294
4295void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4296{
4297 for (int i = 0; i < n; i++)
4298 {
4299 framebuffers[i] = createFramebuffer();
4300 }
4301}
4302
4303void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4304{
4305 for (int i = 0; i < n; i++)
4306 {
4307 renderbuffers[i] = createRenderbuffer();
4308 }
4309}
4310
4311void Context::genTextures(GLsizei n, GLuint *textures)
4312{
4313 for (int i = 0; i < n; i++)
4314 {
4315 textures[i] = createTexture();
4316 }
4317}
4318
4319void Context::getActiveAttrib(GLuint program,
4320 GLuint index,
4321 GLsizei bufsize,
4322 GLsizei *length,
4323 GLint *size,
4324 GLenum *type,
4325 GLchar *name)
4326{
4327 Program *programObject = getProgram(program);
4328 ASSERT(programObject);
4329 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4330}
4331
4332void Context::getActiveUniform(GLuint program,
4333 GLuint index,
4334 GLsizei bufsize,
4335 GLsizei *length,
4336 GLint *size,
4337 GLenum *type,
4338 GLchar *name)
4339{
4340 Program *programObject = getProgram(program);
4341 ASSERT(programObject);
4342 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4343}
4344
4345void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4346{
4347 Program *programObject = getProgram(program);
4348 ASSERT(programObject);
4349 programObject->getAttachedShaders(maxcount, count, shaders);
4350}
4351
4352GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4353{
4354 Program *programObject = getProgram(program);
4355 ASSERT(programObject);
4356 return programObject->getAttributeLocation(name);
4357}
4358
4359void Context::getBooleanv(GLenum pname, GLboolean *params)
4360{
4361 GLenum nativeType;
4362 unsigned int numParams = 0;
4363 getQueryParameterInfo(pname, &nativeType, &numParams);
4364
4365 if (nativeType == GL_BOOL)
4366 {
4367 getBooleanvImpl(pname, params);
4368 }
4369 else
4370 {
4371 CastStateValues(this, nativeType, pname, numParams, params);
4372 }
4373}
4374
4375void Context::getFloatv(GLenum pname, GLfloat *params)
4376{
4377 GLenum nativeType;
4378 unsigned int numParams = 0;
4379 getQueryParameterInfo(pname, &nativeType, &numParams);
4380
4381 if (nativeType == GL_FLOAT)
4382 {
4383 getFloatvImpl(pname, params);
4384 }
4385 else
4386 {
4387 CastStateValues(this, nativeType, pname, numParams, params);
4388 }
4389}
4390
4391void Context::getIntegerv(GLenum pname, GLint *params)
4392{
4393 GLenum nativeType;
4394 unsigned int numParams = 0;
4395 getQueryParameterInfo(pname, &nativeType, &numParams);
4396
4397 if (nativeType == GL_INT)
4398 {
4399 getIntegervImpl(pname, params);
4400 }
4401 else
4402 {
4403 CastStateValues(this, nativeType, pname, numParams, params);
4404 }
4405}
4406
4407void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4408{
4409 Program *programObject = getProgram(program);
4410 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004411 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004412}
4413
Jamie Madillbe849e42017-05-02 15:49:00 -04004414void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004415{
4416 Program *programObject = getProgram(program);
4417 ASSERT(programObject);
4418 programObject->getInfoLog(bufsize, length, infolog);
4419}
4420
4421void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4422{
4423 Shader *shaderObject = getShader(shader);
4424 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004425 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004426}
4427
4428void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4429{
4430 Shader *shaderObject = getShader(shader);
4431 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004432 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004433}
4434
4435void Context::getShaderPrecisionFormat(GLenum shadertype,
4436 GLenum precisiontype,
4437 GLint *range,
4438 GLint *precision)
4439{
4440 // TODO(jmadill): Compute shaders.
4441
4442 switch (shadertype)
4443 {
4444 case GL_VERTEX_SHADER:
4445 switch (precisiontype)
4446 {
4447 case GL_LOW_FLOAT:
4448 mCaps.vertexLowpFloat.get(range, precision);
4449 break;
4450 case GL_MEDIUM_FLOAT:
4451 mCaps.vertexMediumpFloat.get(range, precision);
4452 break;
4453 case GL_HIGH_FLOAT:
4454 mCaps.vertexHighpFloat.get(range, precision);
4455 break;
4456
4457 case GL_LOW_INT:
4458 mCaps.vertexLowpInt.get(range, precision);
4459 break;
4460 case GL_MEDIUM_INT:
4461 mCaps.vertexMediumpInt.get(range, precision);
4462 break;
4463 case GL_HIGH_INT:
4464 mCaps.vertexHighpInt.get(range, precision);
4465 break;
4466
4467 default:
4468 UNREACHABLE();
4469 return;
4470 }
4471 break;
4472
4473 case GL_FRAGMENT_SHADER:
4474 switch (precisiontype)
4475 {
4476 case GL_LOW_FLOAT:
4477 mCaps.fragmentLowpFloat.get(range, precision);
4478 break;
4479 case GL_MEDIUM_FLOAT:
4480 mCaps.fragmentMediumpFloat.get(range, precision);
4481 break;
4482 case GL_HIGH_FLOAT:
4483 mCaps.fragmentHighpFloat.get(range, precision);
4484 break;
4485
4486 case GL_LOW_INT:
4487 mCaps.fragmentLowpInt.get(range, precision);
4488 break;
4489 case GL_MEDIUM_INT:
4490 mCaps.fragmentMediumpInt.get(range, precision);
4491 break;
4492 case GL_HIGH_INT:
4493 mCaps.fragmentHighpInt.get(range, precision);
4494 break;
4495
4496 default:
4497 UNREACHABLE();
4498 return;
4499 }
4500 break;
4501
4502 default:
4503 UNREACHABLE();
4504 return;
4505 }
4506}
4507
4508void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4509{
4510 Shader *shaderObject = getShader(shader);
4511 ASSERT(shaderObject);
4512 shaderObject->getSource(bufsize, length, source);
4513}
4514
4515void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4516{
4517 Program *programObject = getProgram(program);
4518 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004519 programObject->getUniformfv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004520}
4521
4522void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4523{
4524 Program *programObject = getProgram(program);
4525 ASSERT(programObject);
Jamie Madill54164b02017-08-28 15:17:37 -04004526 programObject->getUniformiv(this, location, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004527}
4528
4529GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4530{
4531 Program *programObject = getProgram(program);
4532 ASSERT(programObject);
4533 return programObject->getUniformLocation(name);
4534}
4535
4536GLboolean Context::isBuffer(GLuint buffer)
4537{
4538 if (buffer == 0)
4539 {
4540 return GL_FALSE;
4541 }
4542
4543 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4544}
4545
4546GLboolean Context::isEnabled(GLenum cap)
4547{
4548 return mGLState.getEnableFeature(cap);
4549}
4550
4551GLboolean Context::isFramebuffer(GLuint framebuffer)
4552{
4553 if (framebuffer == 0)
4554 {
4555 return GL_FALSE;
4556 }
4557
4558 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4559}
4560
4561GLboolean Context::isProgram(GLuint program)
4562{
4563 if (program == 0)
4564 {
4565 return GL_FALSE;
4566 }
4567
4568 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4569}
4570
4571GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4572{
4573 if (renderbuffer == 0)
4574 {
4575 return GL_FALSE;
4576 }
4577
4578 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4579}
4580
4581GLboolean Context::isShader(GLuint shader)
4582{
4583 if (shader == 0)
4584 {
4585 return GL_FALSE;
4586 }
4587
4588 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4589}
4590
4591GLboolean Context::isTexture(GLuint texture)
4592{
4593 if (texture == 0)
4594 {
4595 return GL_FALSE;
4596 }
4597
4598 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4599}
4600
4601void Context::linkProgram(GLuint program)
4602{
4603 Program *programObject = getProgram(program);
4604 ASSERT(programObject);
4605 handleError(programObject->link(this));
Martin Radev0abb7a22017-08-28 15:34:45 +03004606 mGLState.onProgramExecutableChange(programObject);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004607}
4608
4609void Context::releaseShaderCompiler()
4610{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004611 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004612}
4613
4614void Context::shaderBinary(GLsizei n,
4615 const GLuint *shaders,
4616 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004617 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004618 GLsizei length)
4619{
4620 // No binary shader formats are supported.
4621 UNIMPLEMENTED();
4622}
4623
4624void Context::shaderSource(GLuint shader,
4625 GLsizei count,
4626 const GLchar *const *string,
4627 const GLint *length)
4628{
4629 Shader *shaderObject = getShader(shader);
4630 ASSERT(shaderObject);
4631 shaderObject->setSource(count, string, length);
4632}
4633
4634void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4635{
4636 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4637}
4638
4639void Context::stencilMask(GLuint mask)
4640{
4641 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4642}
4643
4644void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4645{
4646 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4647}
4648
4649void Context::uniform1f(GLint location, GLfloat x)
4650{
4651 Program *program = mGLState.getProgram();
4652 program->setUniform1fv(location, 1, &x);
4653}
4654
4655void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4656{
4657 Program *program = mGLState.getProgram();
4658 program->setUniform1fv(location, count, v);
4659}
4660
4661void Context::uniform1i(GLint location, GLint x)
4662{
4663 Program *program = mGLState.getProgram();
4664 program->setUniform1iv(location, 1, &x);
4665}
4666
4667void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4668{
4669 Program *program = mGLState.getProgram();
4670 program->setUniform1iv(location, count, v);
4671}
4672
4673void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4674{
4675 GLfloat xy[2] = {x, y};
4676 Program *program = mGLState.getProgram();
4677 program->setUniform2fv(location, 1, xy);
4678}
4679
4680void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4681{
4682 Program *program = mGLState.getProgram();
4683 program->setUniform2fv(location, count, v);
4684}
4685
4686void Context::uniform2i(GLint location, GLint x, GLint y)
4687{
4688 GLint xy[2] = {x, y};
4689 Program *program = mGLState.getProgram();
4690 program->setUniform2iv(location, 1, xy);
4691}
4692
4693void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4694{
4695 Program *program = mGLState.getProgram();
4696 program->setUniform2iv(location, count, v);
4697}
4698
4699void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4700{
4701 GLfloat xyz[3] = {x, y, z};
4702 Program *program = mGLState.getProgram();
4703 program->setUniform3fv(location, 1, xyz);
4704}
4705
4706void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4707{
4708 Program *program = mGLState.getProgram();
4709 program->setUniform3fv(location, count, v);
4710}
4711
4712void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4713{
4714 GLint xyz[3] = {x, y, z};
4715 Program *program = mGLState.getProgram();
4716 program->setUniform3iv(location, 1, xyz);
4717}
4718
4719void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4720{
4721 Program *program = mGLState.getProgram();
4722 program->setUniform3iv(location, count, v);
4723}
4724
4725void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4726{
4727 GLfloat xyzw[4] = {x, y, z, w};
4728 Program *program = mGLState.getProgram();
4729 program->setUniform4fv(location, 1, xyzw);
4730}
4731
4732void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4733{
4734 Program *program = mGLState.getProgram();
4735 program->setUniform4fv(location, count, v);
4736}
4737
4738void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4739{
4740 GLint xyzw[4] = {x, y, z, w};
4741 Program *program = mGLState.getProgram();
4742 program->setUniform4iv(location, 1, xyzw);
4743}
4744
4745void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4746{
4747 Program *program = mGLState.getProgram();
4748 program->setUniform4iv(location, count, v);
4749}
4750
4751void Context::uniformMatrix2fv(GLint location,
4752 GLsizei count,
4753 GLboolean transpose,
4754 const GLfloat *value)
4755{
4756 Program *program = mGLState.getProgram();
4757 program->setUniformMatrix2fv(location, count, transpose, value);
4758}
4759
4760void Context::uniformMatrix3fv(GLint location,
4761 GLsizei count,
4762 GLboolean transpose,
4763 const GLfloat *value)
4764{
4765 Program *program = mGLState.getProgram();
4766 program->setUniformMatrix3fv(location, count, transpose, value);
4767}
4768
4769void Context::uniformMatrix4fv(GLint location,
4770 GLsizei count,
4771 GLboolean transpose,
4772 const GLfloat *value)
4773{
4774 Program *program = mGLState.getProgram();
4775 program->setUniformMatrix4fv(location, count, transpose, value);
4776}
4777
4778void Context::validateProgram(GLuint program)
4779{
4780 Program *programObject = getProgram(program);
4781 ASSERT(programObject);
4782 programObject->validate(mCaps);
4783}
4784
Jamie Madilld04908b2017-06-09 14:15:35 -04004785void Context::getProgramBinary(GLuint program,
4786 GLsizei bufSize,
4787 GLsizei *length,
4788 GLenum *binaryFormat,
4789 void *binary)
4790{
4791 Program *programObject = getProgram(program);
4792 ASSERT(programObject != nullptr);
4793
4794 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4795}
4796
4797void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4798{
4799 Program *programObject = getProgram(program);
4800 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004801
Jamie Madilld04908b2017-06-09 14:15:35 -04004802 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4803}
4804
Jamie Madillff325f12017-08-26 15:06:05 -04004805void Context::uniform1ui(GLint location, GLuint v0)
4806{
4807 Program *program = mGLState.getProgram();
4808 program->setUniform1uiv(location, 1, &v0);
4809}
4810
4811void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4812{
4813 Program *program = mGLState.getProgram();
4814 const GLuint xy[] = {v0, v1};
4815 program->setUniform2uiv(location, 1, xy);
4816}
4817
4818void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4819{
4820 Program *program = mGLState.getProgram();
4821 const GLuint xyz[] = {v0, v1, v2};
4822 program->setUniform3uiv(location, 1, xyz);
4823}
4824
4825void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4826{
4827 Program *program = mGLState.getProgram();
4828 const GLuint xyzw[] = {v0, v1, v2, v3};
4829 program->setUniform4uiv(location, 1, xyzw);
4830}
4831
4832void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4833{
4834 Program *program = mGLState.getProgram();
4835 program->setUniform1uiv(location, count, value);
4836}
4837void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4838{
4839 Program *program = mGLState.getProgram();
4840 program->setUniform2uiv(location, count, value);
4841}
4842
4843void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4844{
4845 Program *program = mGLState.getProgram();
4846 program->setUniform3uiv(location, count, value);
4847}
4848
4849void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4850{
4851 Program *program = mGLState.getProgram();
4852 program->setUniform4uiv(location, count, value);
4853}
4854
Jamie Madillf0e04492017-08-26 15:28:42 -04004855void Context::genQueries(GLsizei n, GLuint *ids)
4856{
4857 for (GLsizei i = 0; i < n; i++)
4858 {
4859 GLuint handle = mQueryHandleAllocator.allocate();
4860 mQueryMap.assign(handle, nullptr);
4861 ids[i] = handle;
4862 }
4863}
4864
4865void Context::deleteQueries(GLsizei n, const GLuint *ids)
4866{
4867 for (int i = 0; i < n; i++)
4868 {
4869 GLuint query = ids[i];
4870
4871 Query *queryObject = nullptr;
4872 if (mQueryMap.erase(query, &queryObject))
4873 {
4874 mQueryHandleAllocator.release(query);
4875 if (queryObject)
4876 {
4877 queryObject->release(this);
4878 }
4879 }
4880 }
4881}
4882
4883GLboolean Context::isQuery(GLuint id)
4884{
4885 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4886}
4887
Jamie Madillc8c95812017-08-26 18:40:09 -04004888void Context::uniformMatrix2x3fv(GLint location,
4889 GLsizei count,
4890 GLboolean transpose,
4891 const GLfloat *value)
4892{
4893 Program *program = mGLState.getProgram();
4894 program->setUniformMatrix2x3fv(location, count, transpose, value);
4895}
4896
4897void Context::uniformMatrix3x2fv(GLint location,
4898 GLsizei count,
4899 GLboolean transpose,
4900 const GLfloat *value)
4901{
4902 Program *program = mGLState.getProgram();
4903 program->setUniformMatrix3x2fv(location, count, transpose, value);
4904}
4905
4906void Context::uniformMatrix2x4fv(GLint location,
4907 GLsizei count,
4908 GLboolean transpose,
4909 const GLfloat *value)
4910{
4911 Program *program = mGLState.getProgram();
4912 program->setUniformMatrix2x4fv(location, count, transpose, value);
4913}
4914
4915void Context::uniformMatrix4x2fv(GLint location,
4916 GLsizei count,
4917 GLboolean transpose,
4918 const GLfloat *value)
4919{
4920 Program *program = mGLState.getProgram();
4921 program->setUniformMatrix4x2fv(location, count, transpose, value);
4922}
4923
4924void Context::uniformMatrix3x4fv(GLint location,
4925 GLsizei count,
4926 GLboolean transpose,
4927 const GLfloat *value)
4928{
4929 Program *program = mGLState.getProgram();
4930 program->setUniformMatrix3x4fv(location, count, transpose, value);
4931}
4932
4933void Context::uniformMatrix4x3fv(GLint location,
4934 GLsizei count,
4935 GLboolean transpose,
4936 const GLfloat *value)
4937{
4938 Program *program = mGLState.getProgram();
4939 program->setUniformMatrix4x3fv(location, count, transpose, value);
4940}
4941
Jamie Madilld7576732017-08-26 18:49:50 -04004942void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
4943{
4944 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4945 {
4946 GLuint vertexArray = arrays[arrayIndex];
4947
4948 if (arrays[arrayIndex] != 0)
4949 {
4950 VertexArray *vertexArrayObject = nullptr;
4951 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
4952 {
4953 if (vertexArrayObject != nullptr)
4954 {
4955 detachVertexArray(vertexArray);
4956 vertexArrayObject->onDestroy(this);
4957 }
4958
4959 mVertexArrayHandleAllocator.release(vertexArray);
4960 }
4961 }
4962 }
4963}
4964
4965void Context::genVertexArrays(GLsizei n, GLuint *arrays)
4966{
4967 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4968 {
4969 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
4970 mVertexArrayMap.assign(vertexArray, nullptr);
4971 arrays[arrayIndex] = vertexArray;
4972 }
4973}
4974
4975bool Context::isVertexArray(GLuint array)
4976{
4977 if (array == 0)
4978 {
4979 return GL_FALSE;
4980 }
4981
4982 VertexArray *vao = getVertexArray(array);
4983 return (vao != nullptr ? GL_TRUE : GL_FALSE);
4984}
4985
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04004986void Context::endTransformFeedback()
4987{
4988 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
4989 transformFeedback->end(this);
4990}
4991
4992void Context::transformFeedbackVaryings(GLuint program,
4993 GLsizei count,
4994 const GLchar *const *varyings,
4995 GLenum bufferMode)
4996{
4997 Program *programObject = getProgram(program);
4998 ASSERT(programObject);
4999 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
5000}
5001
5002void Context::getTransformFeedbackVarying(GLuint program,
5003 GLuint index,
5004 GLsizei bufSize,
5005 GLsizei *length,
5006 GLsizei *size,
5007 GLenum *type,
5008 GLchar *name)
5009{
5010 Program *programObject = getProgram(program);
5011 ASSERT(programObject);
5012 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5013}
5014
5015void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5016{
5017 for (int i = 0; i < n; i++)
5018 {
5019 GLuint transformFeedback = ids[i];
5020 if (transformFeedback == 0)
5021 {
5022 continue;
5023 }
5024
5025 TransformFeedback *transformFeedbackObject = nullptr;
5026 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5027 {
5028 if (transformFeedbackObject != nullptr)
5029 {
5030 detachTransformFeedback(transformFeedback);
5031 transformFeedbackObject->release(this);
5032 }
5033
5034 mTransformFeedbackHandleAllocator.release(transformFeedback);
5035 }
5036 }
5037}
5038
5039void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5040{
5041 for (int i = 0; i < n; i++)
5042 {
5043 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5044 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5045 ids[i] = transformFeedback;
5046 }
5047}
5048
5049bool Context::isTransformFeedback(GLuint id)
5050{
5051 if (id == 0)
5052 {
5053 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5054 // returns FALSE
5055 return GL_FALSE;
5056 }
5057
5058 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5059 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5060}
5061
5062void Context::pauseTransformFeedback()
5063{
5064 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5065 transformFeedback->pause();
5066}
5067
5068void Context::resumeTransformFeedback()
5069{
5070 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5071 transformFeedback->resume();
5072}
5073
Jamie Madill12e957f2017-08-26 21:42:26 -04005074void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5075{
5076 const Program *programObject = getProgram(program);
Jamie Madill54164b02017-08-28 15:17:37 -04005077 programObject->getUniformuiv(this, location, params);
Jamie Madill12e957f2017-08-26 21:42:26 -04005078}
5079
5080GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5081{
5082 const Program *programObject = getProgram(program);
5083 return programObject->getFragDataLocation(name);
5084}
5085
5086void Context::getUniformIndices(GLuint program,
5087 GLsizei uniformCount,
5088 const GLchar *const *uniformNames,
5089 GLuint *uniformIndices)
5090{
5091 const Program *programObject = getProgram(program);
5092 if (!programObject->isLinked())
5093 {
5094 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5095 {
5096 uniformIndices[uniformId] = GL_INVALID_INDEX;
5097 }
5098 }
5099 else
5100 {
5101 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5102 {
5103 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5104 }
5105 }
5106}
5107
5108void Context::getActiveUniformsiv(GLuint program,
5109 GLsizei uniformCount,
5110 const GLuint *uniformIndices,
5111 GLenum pname,
5112 GLint *params)
5113{
5114 const Program *programObject = getProgram(program);
5115 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5116 {
5117 const GLuint index = uniformIndices[uniformId];
5118 params[uniformId] = programObject->getActiveUniformi(index, pname);
5119 }
5120}
5121
5122GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5123{
5124 const Program *programObject = getProgram(program);
5125 return programObject->getUniformBlockIndex(uniformBlockName);
5126}
5127
5128void Context::getActiveUniformBlockiv(GLuint program,
5129 GLuint uniformBlockIndex,
5130 GLenum pname,
5131 GLint *params)
5132{
5133 const Program *programObject = getProgram(program);
5134 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5135}
5136
5137void Context::getActiveUniformBlockName(GLuint program,
5138 GLuint uniformBlockIndex,
5139 GLsizei bufSize,
5140 GLsizei *length,
5141 GLchar *uniformBlockName)
5142{
5143 const Program *programObject = getProgram(program);
5144 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5145}
5146
5147void Context::uniformBlockBinding(GLuint program,
5148 GLuint uniformBlockIndex,
5149 GLuint uniformBlockBinding)
5150{
5151 Program *programObject = getProgram(program);
5152 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5153}
5154
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005155GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5156{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005157 GLuint handle = mState.mSyncs->createSync(mImplementation.get());
5158 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005159
Jamie Madill70b5bb02017-08-28 13:32:37 -04005160 Sync *syncObject = getSync(syncHandle);
5161 Error error = syncObject->set(condition, flags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005162 if (error.isError())
5163 {
Jamie Madill70b5bb02017-08-28 13:32:37 -04005164 deleteSync(syncHandle);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005165 handleError(error);
5166 return nullptr;
5167 }
5168
Jamie Madill70b5bb02017-08-28 13:32:37 -04005169 return syncHandle;
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005170}
5171
5172GLboolean Context::isSync(GLsync sync)
5173{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005174 return (getSync(sync) != nullptr);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005175}
5176
5177GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5178{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005179 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005180
5181 GLenum result = GL_WAIT_FAILED;
5182 handleError(syncObject->clientWait(flags, timeout, &result));
5183 return result;
5184}
5185
5186void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5187{
Jamie Madill70b5bb02017-08-28 13:32:37 -04005188 Sync *syncObject = getSync(sync);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005189 handleError(syncObject->serverWait(flags, timeout));
5190}
5191
5192void Context::getInteger64v(GLenum pname, GLint64 *params)
5193{
5194 GLenum nativeType = GL_NONE;
5195 unsigned int numParams = 0;
5196 getQueryParameterInfo(pname, &nativeType, &numParams);
5197
5198 if (nativeType == GL_INT_64_ANGLEX)
5199 {
5200 getInteger64vImpl(pname, params);
5201 }
5202 else
5203 {
5204 CastStateValues(this, nativeType, pname, numParams, params);
5205 }
5206}
5207
Jamie Madill3ef140a2017-08-26 23:11:21 -04005208void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5209{
5210 Buffer *buffer = mGLState.getTargetBuffer(target);
5211 QueryBufferParameteri64v(buffer, pname, params);
5212}
5213
5214void Context::genSamplers(GLsizei count, GLuint *samplers)
5215{
5216 for (int i = 0; i < count; i++)
5217 {
5218 samplers[i] = mState.mSamplers->createSampler();
5219 }
5220}
5221
5222void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5223{
5224 for (int i = 0; i < count; i++)
5225 {
5226 GLuint sampler = samplers[i];
5227
5228 if (mState.mSamplers->getSampler(sampler))
5229 {
5230 detachSampler(sampler);
5231 }
5232
5233 mState.mSamplers->deleteObject(this, sampler);
5234 }
5235}
5236
5237void Context::getInternalformativ(GLenum target,
5238 GLenum internalformat,
5239 GLenum pname,
5240 GLsizei bufSize,
5241 GLint *params)
5242{
5243 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5244 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5245}
5246
Jamie Madillc29968b2016-01-20 11:17:23 -05005247} // namespace gl