blob: 91ba0f6b7b41addf63aff0d451830f2fcddab2aa [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madill231c7f52017-04-26 13:45:37 -040012#include <string.h>
Jamie Madillb9293972015-02-19 11:07:54 -050013#include <iterator>
14#include <sstream>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Jamie Madill948bbe52017-06-01 13:10:42 -040023#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Fence.h"
25#include "libANGLE/Framebuffer.h"
26#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070037#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040038#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030039#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040040#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040041#include "libANGLE/renderer/ContextImpl.h"
42#include "libANGLE/renderer/EGLImplFactory.h"
43#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Jamie Madillb6664922017-07-25 12:55:04 -040048#define ANGLE_HANDLE_ERR(X) \
49 handleError(X); \
50 return;
51#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR);
52
Ian Ewell3ffd78b2016-01-22 16:09:42 -050053template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050054std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030055 GLsizei numPaths,
56 const void *paths,
57 GLuint pathBase)
58{
59 std::vector<gl::Path *> ret;
60 ret.reserve(numPaths);
61
62 const auto *nameArray = static_cast<const T *>(paths);
63
64 for (GLsizei i = 0; i < numPaths; ++i)
65 {
66 const GLuint pathName = nameArray[i] + pathBase;
67
68 ret.push_back(resourceManager.getPath(pathName));
69 }
70
71 return ret;
72}
73
Geoff Lang4ddf5af2016-12-01 14:30:44 -050074std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030075 GLsizei numPaths,
76 GLenum pathNameType,
77 const void *paths,
78 GLuint pathBase)
79{
80 switch (pathNameType)
81 {
82 case GL_UNSIGNED_BYTE:
83 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_BYTE:
86 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_SHORT:
89 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_SHORT:
92 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
93
94 case GL_UNSIGNED_INT:
95 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
96
97 case GL_INT:
98 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
99 }
100
101 UNREACHABLE();
102 return std::vector<gl::Path *>();
103}
104
105template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400106gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500107{
Geoff Lang2186c382016-10-14 10:54:54 -0400108 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109
110 switch (pname)
111 {
112 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400113 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500114 case GL_QUERY_RESULT_AVAILABLE_EXT:
115 {
116 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400117 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500118 if (!error.isError())
119 {
Geoff Lang2186c382016-10-14 10:54:54 -0400120 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500121 }
122 return error;
123 }
124 default:
125 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500126 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500127 }
128}
129
Geoff Langf6db0982015-08-25 13:04:00 -0400130void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
131{
Geoff Lang1a683462015-09-29 15:09:59 -0400132 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400133 {
134 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
135 tfBufferIndex++)
136 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400137 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400138 transformFeedback->getIndexedBuffer(tfBufferIndex);
139 if (buffer.get() != nullptr)
140 {
141 buffer->onTransformFeedback();
142 }
143 }
144 }
145}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146
147// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500149{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151}
152
Martin Radev1be913c2016-07-11 17:59:16 +0300153EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
154{
155 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
156}
157
Geoff Langeb66a6e2016-10-31 13:06:12 -0400158gl::Version GetClientVersion(const egl::AttributeMap &attribs)
159{
160 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
161}
162
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500163GLenum GetResetStrategy(const egl::AttributeMap &attribs)
164{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400165 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
166 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500167 switch (attrib)
168 {
169 case EGL_NO_RESET_NOTIFICATION:
170 return GL_NO_RESET_NOTIFICATION_EXT;
171 case EGL_LOSE_CONTEXT_ON_RESET:
172 return GL_LOSE_CONTEXT_ON_RESET_EXT;
173 default:
174 UNREACHABLE();
175 return GL_NONE;
176 }
177}
178
179bool GetRobustAccess(const egl::AttributeMap &attribs)
180{
Geoff Lang077f20a2016-11-01 10:08:02 -0400181 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
182 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
183 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184}
185
186bool GetDebug(const egl::AttributeMap &attribs)
187{
Geoff Lang077f20a2016-11-01 10:08:02 -0400188 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
189 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500190}
191
192bool GetNoError(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langc287ea62016-09-16 14:46:51 -0400197bool GetWebGLContext(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
200}
201
Geoff Langf41a7152016-09-19 15:11:17 -0400202bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
205}
206
Geoff Langfeb8c682017-02-13 16:07:35 -0500207bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
208{
209 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
210}
211
Martin Radev9d901792016-07-15 15:58:58 +0300212std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
213{
214 std::string labelName;
215 if (label != nullptr)
216 {
217 size_t labelLength = length < 0 ? strlen(label) : length;
218 labelName = std::string(label, labelLength);
219 }
220 return labelName;
221}
222
223void GetObjectLabelBase(const std::string &objectLabel,
224 GLsizei bufSize,
225 GLsizei *length,
226 GLchar *label)
227{
228 size_t writeLength = objectLabel.length();
229 if (label != nullptr && bufSize > 0)
230 {
231 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
232 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
233 label[writeLength] = '\0';
234 }
235
236 if (length != nullptr)
237 {
238 *length = static_cast<GLsizei>(writeLength);
239 }
240}
241
Geoff Langf6db0982015-08-25 13:04:00 -0400242} // anonymous namespace
243
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000244namespace gl
245{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000246
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400247Context::Context(rx::EGLImplFactory *implFactory,
248 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400249 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500250 TextureManager *shareTextures,
Jamie Madill32447362017-06-28 14:53:52 -0400251 MemoryProgramCache *memoryProgramCache,
Corentin Wallezc295e512017-01-27 17:47:50 -0500252 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400253 const egl::DisplayExtensions &displayExtensions,
254 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300255
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500256 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500257 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500258 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700259 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500260 mCaps,
261 mTextureCaps,
262 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500263 mLimitations,
264 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700265 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400266 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400267 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500268 mClientType(EGL_OPENGL_ES_API),
269 mHasBeenCurrent(false),
270 mContextLost(false),
271 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700272 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500273 mResetStrategy(GetResetStrategy(attribs)),
274 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400275 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
276 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500277 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500278 mWebGLContext(GetWebGLContext(attribs)),
Jamie Madill32447362017-06-28 14:53:52 -0400279 mMemoryProgramCache(memoryProgramCache),
Jamie Madillb3f26b92017-07-19 15:07:41 -0400280 mScratchBuffer(1000u),
281 mZeroFilledBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282{
Geoff Lang077f20a2016-11-01 10:08:02 -0400283 if (mRobustAccess)
284 {
285 UNIMPLEMENTED();
286 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000287
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500288 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700289 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400290
Jamie Madill4928b7c2017-06-20 12:57:39 -0400291 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400292 GetClientArraysEnabled(attribs), robustResourceInit,
293 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100294
Shannon Woods53a94a82014-06-24 15:20:36 -0400295 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400296
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000297 // [OpenGL ES 2.0.24] section 3.7 page 83:
298 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
299 // and cube map texture state vectors respectively associated with them.
300 // In order that access to these initial textures not be lost, they are treated as texture
301 // objects all of whose names are 0.
302
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400304 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500305
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400307 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308
Geoff Langeb66a6e2016-10-31 13:06:12 -0400309 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400310 {
311 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400312 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400313 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400314
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400315 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400316 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400317 }
Geoff Lang3b573612016-10-31 14:08:10 -0400318 if (getClientVersion() >= Version(3, 1))
319 {
320 Texture *zeroTexture2DMultisample =
321 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400322 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800323
324 bindGenericAtomicCounterBuffer(0);
325 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
326 {
327 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
328 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800329
330 bindGenericShaderStorageBuffer(0);
331 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
332 {
333 bindIndexedShaderStorageBuffer(0, i, 0, 0);
334 }
Geoff Lang3b573612016-10-31 14:08:10 -0400335 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000336
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400337 if (mExtensions.textureRectangle)
338 {
339 Texture *zeroTextureRectangle =
340 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
341 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
342 }
343
Ian Ewellbda75592016-04-18 17:25:54 -0400344 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
345 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400346 Texture *zeroTextureExternal =
347 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400348 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400349 }
350
Jamie Madill4928b7c2017-06-20 12:57:39 -0400351 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500352
Jamie Madill57a89722013-07-02 11:57:03 -0400353 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000354 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800355 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000356 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400357
Jamie Madill01a80ee2016-11-07 12:06:18 -0500358 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000359
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000360 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500361 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000362 {
363 bindIndexedUniformBuffer(0, i, 0, -1);
364 }
365
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000366 bindCopyReadBuffer(0);
367 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000368 bindPixelPackBuffer(0);
369 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000370
Geoff Langeb66a6e2016-10-31 13:06:12 -0400371 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400372 {
373 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
374 // In the initial state, a default transform feedback object is bound and treated as
375 // a transform feedback object with a name of zero. That object is bound any time
376 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400377 bindTransformFeedback(0);
378 }
Geoff Langc8058452014-02-03 12:04:11 -0500379
Jamie Madillad9f24e2016-02-12 09:27:24 -0500380 // Initialize dirty bit masks
381 // TODO(jmadill): additional ES3 state
382 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
383 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
384 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
385 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
386 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
387 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400388 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500389 // No dirty objects.
390
391 // Readpixels uses the pack state and read FBO
392 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
393 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
394 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
395 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
396 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400397 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500398 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
399
400 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
401 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
402 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
403 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
404 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
405 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
406 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
407 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
408 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
409 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
410 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
411 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
412
413 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
414 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700415 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500416 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
417 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400418
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400419 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420}
421
Jamie Madill4928b7c2017-06-20 12:57:39 -0400422egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423{
Corentin Wallez80b24112015-08-25 16:41:57 -0400424 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000425 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400426 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400428 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429
Corentin Wallez80b24112015-08-25 16:41:57 -0400430 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400432 if (query.second != nullptr)
433 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400434 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400435 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000436 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400437 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438
Corentin Wallez80b24112015-08-25 16:41:57 -0400439 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400440 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400441 if (vertexArray.second)
442 {
443 vertexArray.second->onDestroy(this);
444 }
Jamie Madill57a89722013-07-02 11:57:03 -0400445 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400446 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400447
Corentin Wallez80b24112015-08-25 16:41:57 -0400448 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500449 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500450 if (transformFeedback.second != nullptr)
451 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500452 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500453 }
Geoff Langc8058452014-02-03 12:04:11 -0500454 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400455 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500456
Jamie Madilldedd7b92014-11-05 16:30:36 -0500457 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400458 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400459 zeroTexture.second->onDestroy(this);
460 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400461 }
462 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463
Corentin Wallezccab69d2017-01-27 16:57:15 -0500464 SafeDelete(mSurfacelessFramebuffer);
465
Jamie Madill4928b7c2017-06-20 12:57:39 -0400466 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400467 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500468
Jamie Madill4928b7c2017-06-20 12:57:39 -0400469 mGLState.reset(this);
470
Jamie Madill6c1f6712017-02-14 19:08:04 -0500471 mState.mBuffers->release(this);
472 mState.mShaderPrograms->release(this);
473 mState.mTextures->release(this);
474 mState.mRenderbuffers->release(this);
475 mState.mSamplers->release(this);
476 mState.mFenceSyncs->release(this);
477 mState.mPaths->release(this);
478 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400479
480 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000481}
482
Jamie Madill70ee0f62017-02-06 16:04:20 -0500483Context::~Context()
484{
485}
486
Jamie Madill4928b7c2017-06-20 12:57:39 -0400487egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488{
Jamie Madill61e16b42017-06-19 11:13:23 -0400489 mCurrentDisplay = display;
490
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000491 if (!mHasBeenCurrent)
492 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500494 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400495 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000496
Corentin Wallezc295e512017-01-27 17:47:50 -0500497 int width = 0;
498 int height = 0;
499 if (surface != nullptr)
500 {
501 width = surface->getWidth();
502 height = surface->getHeight();
503 }
504
505 mGLState.setViewportParams(0, 0, width, height);
506 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000507
508 mHasBeenCurrent = true;
509 }
510
Jamie Madill1b94d432015-08-07 13:23:23 -0400511 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700512 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400513
Jamie Madill4928b7c2017-06-20 12:57:39 -0400514 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500515
516 Framebuffer *newDefault = nullptr;
517 if (surface != nullptr)
518 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400519 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500520 mCurrentSurface = surface;
521 newDefault = surface->getDefaultFramebuffer();
522 }
523 else
524 {
525 if (mSurfacelessFramebuffer == nullptr)
526 {
527 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
528 }
529
530 newDefault = mSurfacelessFramebuffer;
531 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000532
Corentin Wallez37c39792015-08-20 14:19:46 -0400533 // Update default framebuffer, the binding of the previous default
534 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400535 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700536 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400537 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700538 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400539 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700540 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400541 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700542 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400543 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500544 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400545 }
Ian Ewell292f0052016-02-04 10:37:32 -0500546
547 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400548 mImplementation->onMakeCurrent(this);
549 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000550}
551
Jamie Madill4928b7c2017-06-20 12:57:39 -0400552egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400553{
Corentin Wallez37c39792015-08-20 14:19:46 -0400554 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500555 Framebuffer *currentDefault = nullptr;
556 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400557 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500558 currentDefault = mCurrentSurface->getDefaultFramebuffer();
559 }
560 else if (mSurfacelessFramebuffer != nullptr)
561 {
562 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400563 }
564
Corentin Wallezc295e512017-01-27 17:47:50 -0500565 if (mGLState.getReadFramebuffer() == currentDefault)
566 {
567 mGLState.setReadFramebufferBinding(nullptr);
568 }
569 if (mGLState.getDrawFramebuffer() == currentDefault)
570 {
571 mGLState.setDrawFramebufferBinding(nullptr);
572 }
573 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
574
575 if (mCurrentSurface)
576 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400577 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500578 mCurrentSurface = nullptr;
579 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400580
581 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400582}
583
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000584GLuint Context::createBuffer()
585{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500586 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587}
588
589GLuint Context::createProgram()
590{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500591 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592}
593
594GLuint Context::createShader(GLenum type)
595{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500596 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597}
598
599GLuint Context::createTexture()
600{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500601 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000602}
603
604GLuint Context::createRenderbuffer()
605{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500606 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000607}
608
Geoff Lang882033e2014-09-30 11:26:07 -0400609GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400610{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500611 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400612
Cooper Partind8e62a32015-01-29 15:21:25 -0800613 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400614}
615
Sami Väisänene45e53b2016-05-25 10:36:04 +0300616GLuint Context::createPaths(GLsizei range)
617{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500618 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300619 if (resultOrError.isError())
620 {
621 handleError(resultOrError.getError());
622 return 0;
623 }
624 return resultOrError.getResult();
625}
626
Jamie Madill57a89722013-07-02 11:57:03 -0400627GLuint Context::createVertexArray()
628{
Jamie Madill96a483b2017-06-27 16:49:21 -0400629 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
630 mVertexArrayMap.assign(vertexArray, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500631 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400632}
633
Jamie Madilldc356042013-07-19 16:36:57 -0400634GLuint Context::createSampler()
635{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500636 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400637}
638
Geoff Langc8058452014-02-03 12:04:11 -0500639GLuint Context::createTransformFeedback()
640{
Jamie Madill96a483b2017-06-27 16:49:21 -0400641 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
642 mTransformFeedbackMap.assign(transformFeedback, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500643 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500644}
645
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000646// Returns an unused framebuffer name
647GLuint Context::createFramebuffer()
648{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500649 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000650}
651
Jamie Madill33dc8432013-07-26 11:55:05 -0400652GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000653{
Jamie Madill33dc8432013-07-26 11:55:05 -0400654 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400655 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656 return handle;
657}
658
659// Returns an unused query name
660GLuint Context::createQuery()
661{
662 GLuint handle = mQueryHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400663 mQueryMap.assign(handle, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000664 return handle;
665}
666
667void Context::deleteBuffer(GLuint buffer)
668{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500669 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000670 {
671 detachBuffer(buffer);
672 }
Jamie Madill893ab082014-05-16 16:56:10 -0400673
Jamie Madill6c1f6712017-02-14 19:08:04 -0500674 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000675}
676
677void Context::deleteShader(GLuint shader)
678{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500679 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000680}
681
682void Context::deleteProgram(GLuint program)
683{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500684 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000685}
686
687void Context::deleteTexture(GLuint texture)
688{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500689 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000690 {
691 detachTexture(texture);
692 }
693
Jamie Madill6c1f6712017-02-14 19:08:04 -0500694 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000695}
696
697void Context::deleteRenderbuffer(GLuint renderbuffer)
698{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500699 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000700 {
701 detachRenderbuffer(renderbuffer);
702 }
Jamie Madill893ab082014-05-16 16:56:10 -0400703
Jamie Madill6c1f6712017-02-14 19:08:04 -0500704 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000705}
706
Jamie Madillcd055f82013-07-26 11:55:15 -0400707void Context::deleteFenceSync(GLsync fenceSync)
708{
709 // The spec specifies the underlying Fence object is not deleted until all current
710 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
711 // and since our API is currently designed for being called from a single thread, we can delete
712 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500713 mState.mFenceSyncs->deleteObject(this,
714 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400715}
716
Sami Väisänene45e53b2016-05-25 10:36:04 +0300717void Context::deletePaths(GLuint first, GLsizei range)
718{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500719 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300720}
721
722bool Context::hasPathData(GLuint path) const
723{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500724 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300725 if (pathObj == nullptr)
726 return false;
727
728 return pathObj->hasPathData();
729}
730
731bool Context::hasPath(GLuint path) const
732{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500733 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300734}
735
736void Context::setPathCommands(GLuint path,
737 GLsizei numCommands,
738 const GLubyte *commands,
739 GLsizei numCoords,
740 GLenum coordType,
741 const void *coords)
742{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500743 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300744
745 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
746}
747
748void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
749{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500750 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300751
752 switch (pname)
753 {
754 case GL_PATH_STROKE_WIDTH_CHROMIUM:
755 pathObj->setStrokeWidth(value);
756 break;
757 case GL_PATH_END_CAPS_CHROMIUM:
758 pathObj->setEndCaps(static_cast<GLenum>(value));
759 break;
760 case GL_PATH_JOIN_STYLE_CHROMIUM:
761 pathObj->setJoinStyle(static_cast<GLenum>(value));
762 break;
763 case GL_PATH_MITER_LIMIT_CHROMIUM:
764 pathObj->setMiterLimit(value);
765 break;
766 case GL_PATH_STROKE_BOUND_CHROMIUM:
767 pathObj->setStrokeBound(value);
768 break;
769 default:
770 UNREACHABLE();
771 break;
772 }
773}
774
775void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
776{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500777 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300778
779 switch (pname)
780 {
781 case GL_PATH_STROKE_WIDTH_CHROMIUM:
782 *value = pathObj->getStrokeWidth();
783 break;
784 case GL_PATH_END_CAPS_CHROMIUM:
785 *value = static_cast<GLfloat>(pathObj->getEndCaps());
786 break;
787 case GL_PATH_JOIN_STYLE_CHROMIUM:
788 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
789 break;
790 case GL_PATH_MITER_LIMIT_CHROMIUM:
791 *value = pathObj->getMiterLimit();
792 break;
793 case GL_PATH_STROKE_BOUND_CHROMIUM:
794 *value = pathObj->getStrokeBound();
795 break;
796 default:
797 UNREACHABLE();
798 break;
799 }
800}
801
802void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
803{
804 mGLState.setPathStencilFunc(func, ref, mask);
805}
806
Jamie Madill57a89722013-07-02 11:57:03 -0400807void Context::deleteVertexArray(GLuint vertexArray)
808{
Jamie Madill96a483b2017-06-27 16:49:21 -0400809 VertexArray *vertexArrayObject = nullptr;
810 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
Geoff Lang50b3fe82015-12-08 14:49:12 +0000811 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500812 if (vertexArrayObject != nullptr)
813 {
814 detachVertexArray(vertexArray);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400815 vertexArrayObject->onDestroy(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500816 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000817
Geoff Lang36167ab2015-12-07 10:27:14 -0500818 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400819 }
820}
821
Jamie Madilldc356042013-07-19 16:36:57 -0400822void Context::deleteSampler(GLuint sampler)
823{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500824 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400825 {
826 detachSampler(sampler);
827 }
828
Jamie Madill6c1f6712017-02-14 19:08:04 -0500829 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400830}
831
Geoff Langc8058452014-02-03 12:04:11 -0500832void Context::deleteTransformFeedback(GLuint transformFeedback)
833{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400834 if (transformFeedback == 0)
835 {
836 return;
837 }
838
Jamie Madill96a483b2017-06-27 16:49:21 -0400839 TransformFeedback *transformFeedbackObject = nullptr;
840 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
Geoff Langc8058452014-02-03 12:04:11 -0500841 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500842 if (transformFeedbackObject != nullptr)
843 {
844 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500845 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500846 }
847
Geoff Lang36167ab2015-12-07 10:27:14 -0500848 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500849 }
850}
851
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852void Context::deleteFramebuffer(GLuint framebuffer)
853{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500854 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855 {
856 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000857 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500858
Jamie Madill6c1f6712017-02-14 19:08:04 -0500859 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000860}
861
Jamie Madill33dc8432013-07-26 11:55:05 -0400862void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000863{
Jamie Madill96a483b2017-06-27 16:49:21 -0400864 FenceNV *fenceObject = nullptr;
865 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000866 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400867 mFenceNVHandleAllocator.release(fence);
868 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000869 }
870}
871
872void Context::deleteQuery(GLuint query)
873{
Jamie Madill96a483b2017-06-27 16:49:21 -0400874 Query *queryObject = nullptr;
875 if (mQueryMap.erase(query, &queryObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000876 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400877 mQueryHandleAllocator.release(query);
878 if (queryObject)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000879 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400880 queryObject->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000881 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000882 }
883}
884
Geoff Lang70d0f492015-12-10 17:45:46 -0500885Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000886{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500887 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000888}
889
Jamie Madill570f7c82014-07-03 10:38:54 -0400890Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000891{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500892 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000893}
894
Geoff Lang70d0f492015-12-10 17:45:46 -0500895Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000896{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500897 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000898}
899
Jamie Madillcd055f82013-07-26 11:55:15 -0400900FenceSync *Context::getFenceSync(GLsync handle) const
901{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500902 return mState.mFenceSyncs->getFenceSync(
903 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400904}
905
Jamie Madill57a89722013-07-02 11:57:03 -0400906VertexArray *Context::getVertexArray(GLuint handle) const
907{
Jamie Madill96a483b2017-06-27 16:49:21 -0400908 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400909}
910
Jamie Madilldc356042013-07-19 16:36:57 -0400911Sampler *Context::getSampler(GLuint handle) const
912{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500913 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400914}
915
Geoff Langc8058452014-02-03 12:04:11 -0500916TransformFeedback *Context::getTransformFeedback(GLuint handle) const
917{
Jamie Madill96a483b2017-06-27 16:49:21 -0400918 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500919}
920
Geoff Lang70d0f492015-12-10 17:45:46 -0500921LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
922{
923 switch (identifier)
924 {
925 case GL_BUFFER:
926 return getBuffer(name);
927 case GL_SHADER:
928 return getShader(name);
929 case GL_PROGRAM:
930 return getProgram(name);
931 case GL_VERTEX_ARRAY:
932 return getVertexArray(name);
933 case GL_QUERY:
934 return getQuery(name);
935 case GL_TRANSFORM_FEEDBACK:
936 return getTransformFeedback(name);
937 case GL_SAMPLER:
938 return getSampler(name);
939 case GL_TEXTURE:
940 return getTexture(name);
941 case GL_RENDERBUFFER:
942 return getRenderbuffer(name);
943 case GL_FRAMEBUFFER:
944 return getFramebuffer(name);
945 default:
946 UNREACHABLE();
947 return nullptr;
948 }
949}
950
951LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
952{
953 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
954}
955
Martin Radev9d901792016-07-15 15:58:58 +0300956void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
957{
958 LabeledObject *object = getLabeledObject(identifier, name);
959 ASSERT(object != nullptr);
960
961 std::string labelName = GetObjectLabelFromPointer(length, label);
962 object->setLabel(labelName);
963}
964
965void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
966{
967 LabeledObject *object = getLabeledObjectFromPtr(ptr);
968 ASSERT(object != nullptr);
969
970 std::string labelName = GetObjectLabelFromPointer(length, label);
971 object->setLabel(labelName);
972}
973
974void Context::getObjectLabel(GLenum identifier,
975 GLuint name,
976 GLsizei bufSize,
977 GLsizei *length,
978 GLchar *label) const
979{
980 LabeledObject *object = getLabeledObject(identifier, name);
981 ASSERT(object != nullptr);
982
983 const std::string &objectLabel = object->getLabel();
984 GetObjectLabelBase(objectLabel, bufSize, length, label);
985}
986
987void Context::getObjectPtrLabel(const void *ptr,
988 GLsizei bufSize,
989 GLsizei *length,
990 GLchar *label) const
991{
992 LabeledObject *object = getLabeledObjectFromPtr(ptr);
993 ASSERT(object != nullptr);
994
995 const std::string &objectLabel = object->getLabel();
996 GetObjectLabelBase(objectLabel, bufSize, length, label);
997}
998
Jamie Madilldc356042013-07-19 16:36:57 -0400999bool Context::isSampler(GLuint samplerName) const
1000{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001001 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -04001002}
1003
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001004void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +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.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001008}
1009
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001010void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
1011{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001012 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001013 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001014}
1015
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001016void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001017{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001018 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001019 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001020}
1021
Jamie Madilldedd7b92014-11-05 16:30:36 -05001022void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001023{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001025
Jamie Madilldedd7b92014-11-05 16:30:36 -05001026 if (handle == 0)
1027 {
1028 texture = mZeroTextures[target].get();
1029 }
1030 else
1031 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001032 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001033 }
1034
1035 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001036 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001037}
1038
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001039void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001040{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001041 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1042 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001043 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001044}
1045
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001046void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001047{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001048 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1049 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001050 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001051}
1052
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001053void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001054{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001055 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001056 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001057}
1058
Shao80957d92017-02-20 21:25:59 +08001059void Context::bindVertexBuffer(GLuint bindingIndex,
1060 GLuint bufferHandle,
1061 GLintptr offset,
1062 GLsizei stride)
1063{
1064 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001065 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001066}
1067
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001068void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001069{
Geoff Lang76b10c92014-09-05 16:28:14 -04001070 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001071 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001072 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001073 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001074}
1075
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001076void Context::bindImageTexture(GLuint unit,
1077 GLuint texture,
1078 GLint level,
1079 GLboolean layered,
1080 GLint layer,
1081 GLenum access,
1082 GLenum format)
1083{
1084 Texture *tex = mState.mTextures->getTexture(texture);
1085 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1086}
1087
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001088void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001089{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001090 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001091 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001092}
1093
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001094void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1095 GLuint index,
1096 GLintptr offset,
1097 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001098{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001099 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001100 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001101}
1102
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001103void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001104{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001105 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001106 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001107}
1108
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001109void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1110 GLuint index,
1111 GLintptr offset,
1112 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001113{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001114 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001115 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001116}
1117
Jiajia Qin6eafb042016-12-27 17:04:07 +08001118void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1119{
1120 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001121 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001122}
1123
1124void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1125 GLuint index,
1126 GLintptr offset,
1127 GLsizeiptr size)
1128{
1129 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001130 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001131}
1132
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001133void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1134{
1135 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001136 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001137}
1138
1139void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1140 GLuint index,
1141 GLintptr offset,
1142 GLsizeiptr size)
1143{
1144 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001145 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001146}
1147
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001148void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001149{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001150 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001151 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001152}
1153
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001154void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001155{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001156 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001157 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001158}
1159
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001160void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001161{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001162 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001163 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001164}
1165
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001166void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001167{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001168 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001169 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001170}
1171
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172void Context::useProgram(GLuint program)
1173{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001174 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001175}
1176
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001177void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001178{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001179 TransformFeedback *transformFeedback =
1180 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001181 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001182}
1183
Geoff Lang5aad9672014-09-08 11:10:42 -04001184Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001187 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001188
Geoff Lang5aad9672014-09-08 11:10:42 -04001189 // begin query
1190 Error error = queryObject->begin();
1191 if (error.isError())
1192 {
1193 return error;
1194 }
1195
1196 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001197 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001198
He Yunchaoacd18982017-01-04 10:46:42 +08001199 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001200}
1201
Geoff Lang5aad9672014-09-08 11:10:42 -04001202Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001203{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001204 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001205 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206
Geoff Lang5aad9672014-09-08 11:10:42 -04001207 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001208
Geoff Lang5aad9672014-09-08 11:10:42 -04001209 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001210 mGLState.setActiveQuery(this, target, nullptr);
Geoff Lang5aad9672014-09-08 11:10:42 -04001211
1212 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213}
1214
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001215Error Context::queryCounter(GLuint id, GLenum target)
1216{
1217 ASSERT(target == GL_TIMESTAMP_EXT);
1218
1219 Query *queryObject = getQuery(id, true, target);
1220 ASSERT(queryObject);
1221
1222 return queryObject->queryCounter();
1223}
1224
1225void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1226{
1227 switch (pname)
1228 {
1229 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001230 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001231 break;
1232 case GL_QUERY_COUNTER_BITS_EXT:
1233 switch (target)
1234 {
1235 case GL_TIME_ELAPSED_EXT:
1236 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1237 break;
1238 case GL_TIMESTAMP_EXT:
1239 params[0] = getExtensions().queryCounterBitsTimestamp;
1240 break;
1241 default:
1242 UNREACHABLE();
1243 params[0] = 0;
1244 break;
1245 }
1246 break;
1247 default:
1248 UNREACHABLE();
1249 return;
1250 }
1251}
1252
Geoff Lang2186c382016-10-14 10:54:54 -04001253void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001254{
Geoff Lang2186c382016-10-14 10:54:54 -04001255 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001256}
1257
Geoff Lang2186c382016-10-14 10:54:54 -04001258void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001259{
Geoff Lang2186c382016-10-14 10:54:54 -04001260 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001261}
1262
Geoff Lang2186c382016-10-14 10:54:54 -04001263void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001264{
Geoff Lang2186c382016-10-14 10:54:54 -04001265 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001266}
1267
Geoff Lang2186c382016-10-14 10:54:54 -04001268void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001269{
Geoff Lang2186c382016-10-14 10:54:54 -04001270 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001271}
1272
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001273Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001275 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276}
1277
Jamie Madill2f348d22017-06-05 10:50:59 -04001278FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279{
Jamie Madill96a483b2017-06-27 16:49:21 -04001280 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281}
1282
Jamie Madill2f348d22017-06-05 10:50:59 -04001283Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284{
Jamie Madill96a483b2017-06-27 16:49:21 -04001285 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001286 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001287 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001288 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001289
1290 Query *query = mQueryMap.query(handle);
1291 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001292 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001293 query = new Query(mImplementation->createQuery(type), handle);
1294 query->addRef();
1295 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001296 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001297 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001298}
1299
Geoff Lang70d0f492015-12-10 17:45:46 -05001300Query *Context::getQuery(GLuint handle) const
1301{
Jamie Madill96a483b2017-06-27 16:49:21 -04001302 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001303}
1304
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001305Texture *Context::getTargetTexture(GLenum target) const
1306{
Ian Ewellbda75592016-04-18 17:25:54 -04001307 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001308 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001309}
1310
Geoff Lang76b10c92014-09-05 16:28:14 -04001311Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001312{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001313 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001314}
1315
Geoff Lang492a7e42014-11-05 13:27:06 -05001316Compiler *Context::getCompiler() const
1317{
Jamie Madill2f348d22017-06-05 10:50:59 -04001318 if (mCompiler.get() == nullptr)
1319 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001320 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001321 }
1322 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001323}
1324
Jamie Madillc1d770e2017-04-13 17:31:24 -04001325void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326{
1327 switch (pname)
1328 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001329 case GL_SHADER_COMPILER:
1330 *params = GL_TRUE;
1331 break;
1332 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1333 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1334 break;
1335 default:
1336 mGLState.getBooleanv(pname, params);
1337 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001338 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001339}
1340
Jamie Madillc1d770e2017-04-13 17:31:24 -04001341void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001342{
Shannon Woods53a94a82014-06-24 15:20:36 -04001343 // Queries about context capabilities and maximums are answered by Context.
1344 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001345 switch (pname)
1346 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001347 case GL_ALIASED_LINE_WIDTH_RANGE:
1348 params[0] = mCaps.minAliasedLineWidth;
1349 params[1] = mCaps.maxAliasedLineWidth;
1350 break;
1351 case GL_ALIASED_POINT_SIZE_RANGE:
1352 params[0] = mCaps.minAliasedPointSize;
1353 params[1] = mCaps.maxAliasedPointSize;
1354 break;
1355 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1356 ASSERT(mExtensions.textureFilterAnisotropic);
1357 *params = mExtensions.maxTextureAnisotropy;
1358 break;
1359 case GL_MAX_TEXTURE_LOD_BIAS:
1360 *params = mCaps.maxLODBias;
1361 break;
1362
1363 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1364 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1365 {
1366 ASSERT(mExtensions.pathRendering);
1367 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1368 memcpy(params, m, 16 * sizeof(GLfloat));
1369 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001370 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001371
Jamie Madill231c7f52017-04-26 13:45:37 -04001372 default:
1373 mGLState.getFloatv(pname, params);
1374 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001375 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001376}
1377
Jamie Madillc1d770e2017-04-13 17:31:24 -04001378void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001379{
Shannon Woods53a94a82014-06-24 15:20:36 -04001380 // Queries about context capabilities and maximums are answered by Context.
1381 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001382
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001383 switch (pname)
1384 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001385 case GL_MAX_VERTEX_ATTRIBS:
1386 *params = mCaps.maxVertexAttributes;
1387 break;
1388 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1389 *params = mCaps.maxVertexUniformVectors;
1390 break;
1391 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1392 *params = mCaps.maxVertexUniformComponents;
1393 break;
1394 case GL_MAX_VARYING_VECTORS:
1395 *params = mCaps.maxVaryingVectors;
1396 break;
1397 case GL_MAX_VARYING_COMPONENTS:
1398 *params = mCaps.maxVertexOutputComponents;
1399 break;
1400 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1401 *params = mCaps.maxCombinedTextureImageUnits;
1402 break;
1403 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1404 *params = mCaps.maxVertexTextureImageUnits;
1405 break;
1406 case GL_MAX_TEXTURE_IMAGE_UNITS:
1407 *params = mCaps.maxTextureImageUnits;
1408 break;
1409 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1410 *params = mCaps.maxFragmentUniformVectors;
1411 break;
1412 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1413 *params = mCaps.maxFragmentUniformComponents;
1414 break;
1415 case GL_MAX_RENDERBUFFER_SIZE:
1416 *params = mCaps.maxRenderbufferSize;
1417 break;
1418 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1419 *params = mCaps.maxColorAttachments;
1420 break;
1421 case GL_MAX_DRAW_BUFFERS_EXT:
1422 *params = mCaps.maxDrawBuffers;
1423 break;
1424 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1425 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1426 case GL_SUBPIXEL_BITS:
1427 *params = 4;
1428 break;
1429 case GL_MAX_TEXTURE_SIZE:
1430 *params = mCaps.max2DTextureSize;
1431 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001432 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1433 *params = mCaps.maxRectangleTextureSize;
1434 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001435 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1436 *params = mCaps.maxCubeMapTextureSize;
1437 break;
1438 case GL_MAX_3D_TEXTURE_SIZE:
1439 *params = mCaps.max3DTextureSize;
1440 break;
1441 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1442 *params = mCaps.maxArrayTextureLayers;
1443 break;
1444 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1445 *params = mCaps.uniformBufferOffsetAlignment;
1446 break;
1447 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1448 *params = mCaps.maxUniformBufferBindings;
1449 break;
1450 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1451 *params = mCaps.maxVertexUniformBlocks;
1452 break;
1453 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1454 *params = mCaps.maxFragmentUniformBlocks;
1455 break;
1456 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1457 *params = mCaps.maxCombinedTextureImageUnits;
1458 break;
1459 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1460 *params = mCaps.maxVertexOutputComponents;
1461 break;
1462 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1463 *params = mCaps.maxFragmentInputComponents;
1464 break;
1465 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1466 *params = mCaps.minProgramTexelOffset;
1467 break;
1468 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1469 *params = mCaps.maxProgramTexelOffset;
1470 break;
1471 case GL_MAJOR_VERSION:
1472 *params = getClientVersion().major;
1473 break;
1474 case GL_MINOR_VERSION:
1475 *params = getClientVersion().minor;
1476 break;
1477 case GL_MAX_ELEMENTS_INDICES:
1478 *params = mCaps.maxElementsIndices;
1479 break;
1480 case GL_MAX_ELEMENTS_VERTICES:
1481 *params = mCaps.maxElementsVertices;
1482 break;
1483 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1484 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1485 break;
1486 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1487 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1488 break;
1489 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1490 *params = mCaps.maxTransformFeedbackSeparateComponents;
1491 break;
1492 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1493 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1494 break;
1495 case GL_MAX_SAMPLES_ANGLE:
1496 *params = mCaps.maxSamples;
1497 break;
1498 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001499 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001500 params[0] = mCaps.maxViewportWidth;
1501 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001502 }
1503 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001504 case GL_COMPRESSED_TEXTURE_FORMATS:
1505 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1506 params);
1507 break;
1508 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1509 *params = mResetStrategy;
1510 break;
1511 case GL_NUM_SHADER_BINARY_FORMATS:
1512 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1513 break;
1514 case GL_SHADER_BINARY_FORMATS:
1515 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1516 break;
1517 case GL_NUM_PROGRAM_BINARY_FORMATS:
1518 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1519 break;
1520 case GL_PROGRAM_BINARY_FORMATS:
1521 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1522 break;
1523 case GL_NUM_EXTENSIONS:
1524 *params = static_cast<GLint>(mExtensionStrings.size());
1525 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001526
Jamie Madill231c7f52017-04-26 13:45:37 -04001527 // GL_KHR_debug
1528 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1529 *params = mExtensions.maxDebugMessageLength;
1530 break;
1531 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1532 *params = mExtensions.maxDebugLoggedMessages;
1533 break;
1534 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1535 *params = mExtensions.maxDebugGroupStackDepth;
1536 break;
1537 case GL_MAX_LABEL_LENGTH:
1538 *params = mExtensions.maxLabelLength;
1539 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001540
Martin Radeve5285d22017-07-14 16:23:53 +03001541 // GL_ANGLE_multiview
1542 case GL_MAX_VIEWS_ANGLE:
1543 *params = mExtensions.maxViews;
1544 break;
1545
Jamie Madill231c7f52017-04-26 13:45:37 -04001546 // GL_EXT_disjoint_timer_query
1547 case GL_GPU_DISJOINT_EXT:
1548 *params = mImplementation->getGPUDisjoint();
1549 break;
1550 case GL_MAX_FRAMEBUFFER_WIDTH:
1551 *params = mCaps.maxFramebufferWidth;
1552 break;
1553 case GL_MAX_FRAMEBUFFER_HEIGHT:
1554 *params = mCaps.maxFramebufferHeight;
1555 break;
1556 case GL_MAX_FRAMEBUFFER_SAMPLES:
1557 *params = mCaps.maxFramebufferSamples;
1558 break;
1559 case GL_MAX_SAMPLE_MASK_WORDS:
1560 *params = mCaps.maxSampleMaskWords;
1561 break;
1562 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1563 *params = mCaps.maxColorTextureSamples;
1564 break;
1565 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1566 *params = mCaps.maxDepthTextureSamples;
1567 break;
1568 case GL_MAX_INTEGER_SAMPLES:
1569 *params = mCaps.maxIntegerSamples;
1570 break;
1571 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1572 *params = mCaps.maxVertexAttribRelativeOffset;
1573 break;
1574 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1575 *params = mCaps.maxVertexAttribBindings;
1576 break;
1577 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1578 *params = mCaps.maxVertexAttribStride;
1579 break;
1580 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1581 *params = mCaps.maxVertexAtomicCounterBuffers;
1582 break;
1583 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1584 *params = mCaps.maxVertexAtomicCounters;
1585 break;
1586 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1587 *params = mCaps.maxVertexImageUniforms;
1588 break;
1589 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1590 *params = mCaps.maxVertexShaderStorageBlocks;
1591 break;
1592 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1593 *params = mCaps.maxFragmentAtomicCounterBuffers;
1594 break;
1595 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1596 *params = mCaps.maxFragmentAtomicCounters;
1597 break;
1598 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1599 *params = mCaps.maxFragmentImageUniforms;
1600 break;
1601 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1602 *params = mCaps.maxFragmentShaderStorageBlocks;
1603 break;
1604 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1605 *params = mCaps.minProgramTextureGatherOffset;
1606 break;
1607 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1608 *params = mCaps.maxProgramTextureGatherOffset;
1609 break;
1610 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1611 *params = mCaps.maxComputeWorkGroupInvocations;
1612 break;
1613 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1614 *params = mCaps.maxComputeUniformBlocks;
1615 break;
1616 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1617 *params = mCaps.maxComputeTextureImageUnits;
1618 break;
1619 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1620 *params = mCaps.maxComputeSharedMemorySize;
1621 break;
1622 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1623 *params = mCaps.maxComputeUniformComponents;
1624 break;
1625 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1626 *params = mCaps.maxComputeAtomicCounterBuffers;
1627 break;
1628 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1629 *params = mCaps.maxComputeAtomicCounters;
1630 break;
1631 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1632 *params = mCaps.maxComputeImageUniforms;
1633 break;
1634 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1635 *params = mCaps.maxCombinedComputeUniformComponents;
1636 break;
1637 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1638 *params = mCaps.maxComputeShaderStorageBlocks;
1639 break;
1640 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1641 *params = mCaps.maxCombinedShaderOutputResources;
1642 break;
1643 case GL_MAX_UNIFORM_LOCATIONS:
1644 *params = mCaps.maxUniformLocations;
1645 break;
1646 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1647 *params = mCaps.maxAtomicCounterBufferBindings;
1648 break;
1649 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1650 *params = mCaps.maxAtomicCounterBufferSize;
1651 break;
1652 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1653 *params = mCaps.maxCombinedAtomicCounterBuffers;
1654 break;
1655 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1656 *params = mCaps.maxCombinedAtomicCounters;
1657 break;
1658 case GL_MAX_IMAGE_UNITS:
1659 *params = mCaps.maxImageUnits;
1660 break;
1661 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1662 *params = mCaps.maxCombinedImageUniforms;
1663 break;
1664 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1665 *params = mCaps.maxShaderStorageBufferBindings;
1666 break;
1667 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1668 *params = mCaps.maxCombinedShaderStorageBlocks;
1669 break;
1670 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1671 *params = mCaps.shaderStorageBufferOffsetAlignment;
1672 break;
1673 default:
1674 mGLState.getIntegerv(this, pname, params);
1675 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001676 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001677}
1678
Jamie Madill893ab082014-05-16 16:56:10 -04001679void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001680{
Shannon Woods53a94a82014-06-24 15:20:36 -04001681 // Queries about context capabilities and maximums are answered by Context.
1682 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001683 switch (pname)
1684 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001685 case GL_MAX_ELEMENT_INDEX:
1686 *params = mCaps.maxElementIndex;
1687 break;
1688 case GL_MAX_UNIFORM_BLOCK_SIZE:
1689 *params = mCaps.maxUniformBlockSize;
1690 break;
1691 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1692 *params = mCaps.maxCombinedVertexUniformComponents;
1693 break;
1694 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1695 *params = mCaps.maxCombinedFragmentUniformComponents;
1696 break;
1697 case GL_MAX_SERVER_WAIT_TIMEOUT:
1698 *params = mCaps.maxServerWaitTimeout;
1699 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001700
Jamie Madill231c7f52017-04-26 13:45:37 -04001701 // GL_EXT_disjoint_timer_query
1702 case GL_TIMESTAMP_EXT:
1703 *params = mImplementation->getTimestamp();
1704 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001705
Jamie Madill231c7f52017-04-26 13:45:37 -04001706 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1707 *params = mCaps.maxShaderStorageBlockSize;
1708 break;
1709 default:
1710 UNREACHABLE();
1711 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001712 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001713}
1714
Geoff Lang70d0f492015-12-10 17:45:46 -05001715void Context::getPointerv(GLenum pname, void **params) const
1716{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001717 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001718}
1719
Martin Radev66fb8202016-07-28 11:45:20 +03001720void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001721{
Shannon Woods53a94a82014-06-24 15:20:36 -04001722 // Queries about context capabilities and maximums are answered by Context.
1723 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001724
1725 GLenum nativeType;
1726 unsigned int numParams;
1727 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1728 ASSERT(queryStatus);
1729
1730 if (nativeType == GL_INT)
1731 {
1732 switch (target)
1733 {
1734 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1735 ASSERT(index < 3u);
1736 *data = mCaps.maxComputeWorkGroupCount[index];
1737 break;
1738 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1739 ASSERT(index < 3u);
1740 *data = mCaps.maxComputeWorkGroupSize[index];
1741 break;
1742 default:
1743 mGLState.getIntegeri_v(target, index, data);
1744 }
1745 }
1746 else
1747 {
1748 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1749 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001750}
1751
Martin Radev66fb8202016-07-28 11:45:20 +03001752void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001753{
Shannon Woods53a94a82014-06-24 15:20:36 -04001754 // Queries about context capabilities and maximums are answered by Context.
1755 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001756
1757 GLenum nativeType;
1758 unsigned int numParams;
1759 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1760 ASSERT(queryStatus);
1761
1762 if (nativeType == GL_INT_64_ANGLEX)
1763 {
1764 mGLState.getInteger64i_v(target, index, data);
1765 }
1766 else
1767 {
1768 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1769 }
1770}
1771
1772void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1773{
1774 // Queries about context capabilities and maximums are answered by Context.
1775 // Queries about current GL state values are answered by State.
1776
1777 GLenum nativeType;
1778 unsigned int numParams;
1779 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1780 ASSERT(queryStatus);
1781
1782 if (nativeType == GL_BOOL)
1783 {
1784 mGLState.getBooleani_v(target, index, data);
1785 }
1786 else
1787 {
1788 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1789 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001790}
1791
He Yunchao010e4db2017-03-03 14:22:06 +08001792void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1793{
1794 Buffer *buffer = mGLState.getTargetBuffer(target);
1795 QueryBufferParameteriv(buffer, pname, params);
1796}
1797
1798void Context::getFramebufferAttachmentParameteriv(GLenum target,
1799 GLenum attachment,
1800 GLenum pname,
1801 GLint *params)
1802{
1803 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1804 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1805}
1806
1807void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1808{
1809 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1810 QueryRenderbufferiv(this, renderbuffer, pname, params);
1811}
1812
1813void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1814{
1815 Texture *texture = getTargetTexture(target);
1816 QueryTexParameterfv(texture, pname, params);
1817}
1818
1819void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1820{
1821 Texture *texture = getTargetTexture(target);
1822 QueryTexParameteriv(texture, pname, params);
1823}
1824void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1825{
1826 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001827 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001828}
1829
1830void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1831{
1832 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001833 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001834}
1835
1836void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1837{
1838 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001839 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001840}
1841
1842void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1843{
1844 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001845 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001846}
1847
Jamie Madill675fe712016-12-19 13:07:54 -05001848void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001849{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001850 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001851 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1852 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001853}
1854
Jamie Madill675fe712016-12-19 13:07:54 -05001855void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001856{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001857 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001858 ANGLE_CONTEXT_TRY(
1859 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1860 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001861}
1862
Jamie Madill876429b2017-04-20 15:46:24 -04001863void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001864{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001865 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001866 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001867}
1868
Jamie Madill675fe712016-12-19 13:07:54 -05001869void Context::drawElementsInstanced(GLenum mode,
1870 GLsizei count,
1871 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001872 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001873 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001874{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001875 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001876 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001877 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001878}
1879
Jamie Madill675fe712016-12-19 13:07:54 -05001880void Context::drawRangeElements(GLenum mode,
1881 GLuint start,
1882 GLuint end,
1883 GLsizei count,
1884 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001885 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001886{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001887 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001888 ANGLE_CONTEXT_TRY(
1889 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001890}
1891
Jamie Madill876429b2017-04-20 15:46:24 -04001892void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001893{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001894 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001895 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001896}
1897
Jamie Madill876429b2017-04-20 15:46:24 -04001898void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001899{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001900 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001901 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001902}
1903
Jamie Madill675fe712016-12-19 13:07:54 -05001904void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001905{
Jamie Madill675fe712016-12-19 13:07:54 -05001906 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001907}
1908
Jamie Madill675fe712016-12-19 13:07:54 -05001909void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001910{
Jamie Madill675fe712016-12-19 13:07:54 -05001911 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001912}
1913
Austin Kinross6ee1e782015-05-29 17:05:37 -07001914void Context::insertEventMarker(GLsizei length, const char *marker)
1915{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001916 ASSERT(mImplementation);
1917 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001918}
1919
1920void Context::pushGroupMarker(GLsizei length, const char *marker)
1921{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001922 ASSERT(mImplementation);
1923 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001924}
1925
1926void Context::popGroupMarker()
1927{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001928 ASSERT(mImplementation);
1929 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001930}
1931
Geoff Langd8605522016-04-13 10:19:12 -04001932void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1933{
1934 Program *programObject = getProgram(program);
1935 ASSERT(programObject);
1936
1937 programObject->bindUniformLocation(location, name);
1938}
1939
Sami Väisänena797e062016-05-12 15:23:40 +03001940void Context::setCoverageModulation(GLenum components)
1941{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001942 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001943}
1944
Sami Väisänene45e53b2016-05-25 10:36:04 +03001945void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1946{
1947 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1948}
1949
1950void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1951{
1952 GLfloat I[16];
1953 angle::Matrix<GLfloat>::setToIdentity(I);
1954
1955 mGLState.loadPathRenderingMatrix(matrixMode, I);
1956}
1957
1958void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1959{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001960 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001961 if (!pathObj)
1962 return;
1963
1964 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1965 syncRendererState();
1966
1967 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1968}
1969
1970void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1971{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001972 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001973 if (!pathObj)
1974 return;
1975
1976 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1977 syncRendererState();
1978
1979 mImplementation->stencilStrokePath(pathObj, reference, mask);
1980}
1981
1982void Context::coverFillPath(GLuint path, GLenum coverMode)
1983{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001984 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001985 if (!pathObj)
1986 return;
1987
1988 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1989 syncRendererState();
1990
1991 mImplementation->coverFillPath(pathObj, coverMode);
1992}
1993
1994void Context::coverStrokePath(GLuint path, GLenum coverMode)
1995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001996 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001997 if (!pathObj)
1998 return;
1999
2000 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2001 syncRendererState();
2002
2003 mImplementation->coverStrokePath(pathObj, coverMode);
2004}
2005
2006void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
2007{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002008 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002009 if (!pathObj)
2010 return;
2011
2012 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2013 syncRendererState();
2014
2015 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
2016}
2017
2018void Context::stencilThenCoverStrokePath(GLuint path,
2019 GLint reference,
2020 GLuint mask,
2021 GLenum coverMode)
2022{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002023 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002024 if (!pathObj)
2025 return;
2026
2027 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2028 syncRendererState();
2029
2030 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2031}
2032
Sami Väisänend59ca052016-06-21 16:10:00 +03002033void Context::coverFillPathInstanced(GLsizei numPaths,
2034 GLenum pathNameType,
2035 const void *paths,
2036 GLuint pathBase,
2037 GLenum coverMode,
2038 GLenum transformType,
2039 const GLfloat *transformValues)
2040{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002041 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002042
2043 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2044 syncRendererState();
2045
2046 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2047}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002048
Sami Väisänend59ca052016-06-21 16:10:00 +03002049void Context::coverStrokePathInstanced(GLsizei numPaths,
2050 GLenum pathNameType,
2051 const void *paths,
2052 GLuint pathBase,
2053 GLenum coverMode,
2054 GLenum transformType,
2055 const GLfloat *transformValues)
2056{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002057 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002058
2059 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2060 syncRendererState();
2061
2062 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2063 transformValues);
2064}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002065
Sami Väisänend59ca052016-06-21 16:10:00 +03002066void Context::stencilFillPathInstanced(GLsizei numPaths,
2067 GLenum pathNameType,
2068 const void *paths,
2069 GLuint pathBase,
2070 GLenum fillMode,
2071 GLuint mask,
2072 GLenum transformType,
2073 const GLfloat *transformValues)
2074{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002075 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002076
2077 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2078 syncRendererState();
2079
2080 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2081 transformValues);
2082}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002083
Sami Väisänend59ca052016-06-21 16:10:00 +03002084void Context::stencilStrokePathInstanced(GLsizei numPaths,
2085 GLenum pathNameType,
2086 const void *paths,
2087 GLuint pathBase,
2088 GLint reference,
2089 GLuint mask,
2090 GLenum transformType,
2091 const GLfloat *transformValues)
2092{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002093 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002094
2095 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2096 syncRendererState();
2097
2098 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2099 transformValues);
2100}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002101
Sami Väisänend59ca052016-06-21 16:10:00 +03002102void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2103 GLenum pathNameType,
2104 const void *paths,
2105 GLuint pathBase,
2106 GLenum fillMode,
2107 GLuint mask,
2108 GLenum coverMode,
2109 GLenum transformType,
2110 const GLfloat *transformValues)
2111{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002112 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002113
2114 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2115 syncRendererState();
2116
2117 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2118 transformType, transformValues);
2119}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002120
Sami Väisänend59ca052016-06-21 16:10:00 +03002121void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2122 GLenum pathNameType,
2123 const void *paths,
2124 GLuint pathBase,
2125 GLint reference,
2126 GLuint mask,
2127 GLenum coverMode,
2128 GLenum transformType,
2129 const GLfloat *transformValues)
2130{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002131 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002132
2133 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2134 syncRendererState();
2135
2136 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2137 transformType, transformValues);
2138}
2139
Sami Väisänen46eaa942016-06-29 10:26:37 +03002140void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2141{
2142 auto *programObject = getProgram(program);
2143
2144 programObject->bindFragmentInputLocation(location, name);
2145}
2146
2147void Context::programPathFragmentInputGen(GLuint program,
2148 GLint location,
2149 GLenum genMode,
2150 GLint components,
2151 const GLfloat *coeffs)
2152{
2153 auto *programObject = getProgram(program);
2154
Jamie Madillbd044ed2017-06-05 12:59:21 -04002155 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002156}
2157
jchen1015015f72017-03-16 13:54:21 +08002158GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2159{
jchen10fd7c3b52017-03-21 15:36:03 +08002160 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002161 return QueryProgramResourceIndex(programObject, programInterface, name);
2162}
2163
jchen10fd7c3b52017-03-21 15:36:03 +08002164void Context::getProgramResourceName(GLuint program,
2165 GLenum programInterface,
2166 GLuint index,
2167 GLsizei bufSize,
2168 GLsizei *length,
2169 GLchar *name)
2170{
2171 const auto *programObject = getProgram(program);
2172 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2173}
2174
jchen10191381f2017-04-11 13:59:04 +08002175GLint Context::getProgramResourceLocation(GLuint program,
2176 GLenum programInterface,
2177 const GLchar *name)
2178{
2179 const auto *programObject = getProgram(program);
2180 return QueryProgramResourceLocation(programObject, programInterface, name);
2181}
2182
jchen10880683b2017-04-12 16:21:55 +08002183void Context::getProgramResourceiv(GLuint program,
2184 GLenum programInterface,
2185 GLuint index,
2186 GLsizei propCount,
2187 const GLenum *props,
2188 GLsizei bufSize,
2189 GLsizei *length,
2190 GLint *params)
2191{
2192 const auto *programObject = getProgram(program);
2193 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2194 length, params);
2195}
2196
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002197Error Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002198{
Geoff Langda5777c2014-07-11 09:52:58 -04002199 if (error.isError())
2200 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002201 GLenum code = error.getCode();
2202 mErrors.insert(code);
2203 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2204 {
2205 markContextLost();
2206 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002207
2208 if (!error.getMessage().empty())
2209 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002210 auto *debug = &mGLState.getDebug();
2211 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2212 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002213 }
Geoff Langda5777c2014-07-11 09:52:58 -04002214 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002215
2216 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002217}
2218
2219// Get one of the recorded errors and clear its flag, if any.
2220// [OpenGL ES 2.0.24] section 2.5 page 13.
2221GLenum Context::getError()
2222{
Geoff Langda5777c2014-07-11 09:52:58 -04002223 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002224 {
Geoff Langda5777c2014-07-11 09:52:58 -04002225 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002226 }
Geoff Langda5777c2014-07-11 09:52:58 -04002227 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002228 {
Geoff Langda5777c2014-07-11 09:52:58 -04002229 GLenum error = *mErrors.begin();
2230 mErrors.erase(mErrors.begin());
2231 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002232 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002233}
2234
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002235// NOTE: this function should not assume that this context is current!
2236void Context::markContextLost()
2237{
2238 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002239 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002240 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002241 mContextLostForced = true;
2242 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002243 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002244}
2245
2246bool Context::isContextLost()
2247{
2248 return mContextLost;
2249}
2250
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002251GLenum Context::getResetStatus()
2252{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002253 // Even if the application doesn't want to know about resets, we want to know
2254 // as it will allow us to skip all the calls.
2255 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002256 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002257 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002258 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002259 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002260 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002261
2262 // EXT_robustness, section 2.6: If the reset notification behavior is
2263 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2264 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2265 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002266 }
2267
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002268 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2269 // status should be returned at least once, and GL_NO_ERROR should be returned
2270 // once the device has finished resetting.
2271 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002272 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002273 ASSERT(mResetStatus == GL_NO_ERROR);
2274 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002275
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002276 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002277 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002278 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002279 }
2280 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002281 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002282 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002283 // If markContextLost was used to mark the context lost then
2284 // assume that is not recoverable, and continue to report the
2285 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002286 mResetStatus = mImplementation->getResetStatus();
2287 }
Jamie Madill893ab082014-05-16 16:56:10 -04002288
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002289 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002290}
2291
2292bool Context::isResetNotificationEnabled()
2293{
2294 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2295}
2296
Corentin Walleze3b10e82015-05-20 11:06:25 -04002297const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002298{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002299 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002300}
2301
2302EGLenum Context::getClientType() const
2303{
2304 return mClientType;
2305}
2306
2307EGLenum Context::getRenderBuffer() const
2308{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002309 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2310 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002311 {
2312 return EGL_NONE;
2313 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002314
2315 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2316 ASSERT(backAttachment != nullptr);
2317 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002318}
2319
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002320VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002321{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002322 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002323 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2324 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002325 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002326 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2327 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002328
Jamie Madill96a483b2017-06-27 16:49:21 -04002329 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002330 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002331
2332 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002333}
2334
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002335TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002336{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002337 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002338 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2339 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002340 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002341 transformFeedback =
2342 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002343 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002344 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002345 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002346
2347 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002348}
2349
2350bool Context::isVertexArrayGenerated(GLuint vertexArray)
2351{
Jamie Madill96a483b2017-06-27 16:49:21 -04002352 ASSERT(mVertexArrayMap.contains(0));
2353 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002354}
2355
2356bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2357{
Jamie Madill96a483b2017-06-27 16:49:21 -04002358 ASSERT(mTransformFeedbackMap.contains(0));
2359 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002360}
2361
Shannon Woods53a94a82014-06-24 15:20:36 -04002362void Context::detachTexture(GLuint texture)
2363{
2364 // Simple pass-through to State's detachTexture method, as textures do not require
2365 // allocation map management either here or in the resource manager at detach time.
2366 // Zero textures are held by the Context, and we don't attempt to request them from
2367 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002368 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002369}
2370
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002371void Context::detachBuffer(GLuint buffer)
2372{
Yuly Novikov5807a532015-12-03 13:01:22 -05002373 // Simple pass-through to State's detachBuffer method, since
2374 // only buffer attachments to container objects that are bound to the current context
2375 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002376
Yuly Novikov5807a532015-12-03 13:01:22 -05002377 // [OpenGL ES 3.2] section 5.1.2 page 45:
2378 // Attachments to unbound container objects, such as
2379 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2380 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002381 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002382}
2383
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002384void Context::detachFramebuffer(GLuint framebuffer)
2385{
Shannon Woods53a94a82014-06-24 15:20:36 -04002386 // Framebuffer detachment is handled by Context, because 0 is a valid
2387 // Framebuffer object, and a pointer to it must be passed from Context
2388 // to State at binding time.
2389
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002390 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002391 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2392 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2393 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002394
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002395 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002396 {
2397 bindReadFramebuffer(0);
2398 }
2399
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002400 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002401 {
2402 bindDrawFramebuffer(0);
2403 }
2404}
2405
2406void Context::detachRenderbuffer(GLuint renderbuffer)
2407{
Jamie Madilla02315b2017-02-23 14:14:47 -05002408 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002409}
2410
Jamie Madill57a89722013-07-02 11:57:03 -04002411void Context::detachVertexArray(GLuint vertexArray)
2412{
Jamie Madill77a72f62015-04-14 11:18:32 -04002413 // Vertex array detachment is handled by Context, because 0 is a valid
2414 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002415 // binding time.
2416
Jamie Madill57a89722013-07-02 11:57:03 -04002417 // [OpenGL ES 3.0.2] section 2.10 page 43:
2418 // If a vertex array object that is currently bound is deleted, the binding
2419 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002420 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002421 {
2422 bindVertexArray(0);
2423 }
2424}
2425
Geoff Langc8058452014-02-03 12:04:11 -05002426void Context::detachTransformFeedback(GLuint transformFeedback)
2427{
Corentin Walleza2257da2016-04-19 16:43:12 -04002428 // Transform feedback detachment is handled by Context, because 0 is a valid
2429 // transform feedback, and a pointer to it must be passed from Context to State at
2430 // binding time.
2431
2432 // The OpenGL specification doesn't mention what should happen when the currently bound
2433 // transform feedback object is deleted. Since it is a container object, we treat it like
2434 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002435 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002436 {
2437 bindTransformFeedback(0);
2438 }
Geoff Langc8058452014-02-03 12:04:11 -05002439}
2440
Jamie Madilldc356042013-07-19 16:36:57 -04002441void Context::detachSampler(GLuint sampler)
2442{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002443 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002444}
2445
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002446void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2447{
Shaodde78e82017-05-22 14:13:27 +08002448 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002449}
2450
Jamie Madille29d1672013-07-19 16:36:57 -04002451void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2452{
Geoff Langc1984ed2016-10-07 12:41:00 -04002453 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002454 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002455 SetSamplerParameteri(samplerObject, pname, param);
2456}
Jamie Madille29d1672013-07-19 16:36:57 -04002457
Geoff Langc1984ed2016-10-07 12:41:00 -04002458void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2459{
2460 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002461 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002462 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002463}
2464
2465void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2466{
Geoff Langc1984ed2016-10-07 12:41:00 -04002467 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002468 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002469 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002470}
2471
Geoff Langc1984ed2016-10-07 12:41:00 -04002472void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002473{
Geoff Langc1984ed2016-10-07 12:41:00 -04002474 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002475 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002476 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002477}
2478
Geoff Langc1984ed2016-10-07 12:41:00 -04002479void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002480{
Geoff Langc1984ed2016-10-07 12:41:00 -04002481 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002482 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002483 QuerySamplerParameteriv(samplerObject, pname, params);
2484}
Jamie Madill9675b802013-07-19 16:36:59 -04002485
Geoff Langc1984ed2016-10-07 12:41:00 -04002486void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2487{
2488 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002489 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002490 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002491}
2492
Olli Etuahof0fee072016-03-30 15:11:58 +03002493void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2494{
2495 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002496 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002497}
2498
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002499void Context::initRendererString()
2500{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002501 std::ostringstream rendererString;
2502 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002503 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002504 rendererString << ")";
2505
Geoff Langcec35902014-04-16 10:52:36 -04002506 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002507}
2508
Geoff Langc339c4e2016-11-29 10:37:36 -05002509void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002510{
Geoff Langc339c4e2016-11-29 10:37:36 -05002511 const Version &clientVersion = getClientVersion();
2512
2513 std::ostringstream versionString;
2514 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2515 << ANGLE_VERSION_STRING << ")";
2516 mVersionString = MakeStaticString(versionString.str());
2517
2518 std::ostringstream shadingLanguageVersionString;
2519 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2520 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2521 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2522 << ")";
2523 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002524}
2525
Geoff Langcec35902014-04-16 10:52:36 -04002526void Context::initExtensionStrings()
2527{
Geoff Langc339c4e2016-11-29 10:37:36 -05002528 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2529 std::ostringstream combinedStringStream;
2530 std::copy(strings.begin(), strings.end(),
2531 std::ostream_iterator<const char *>(combinedStringStream, " "));
2532 return MakeStaticString(combinedStringStream.str());
2533 };
2534
2535 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002536 for (const auto &extensionString : mExtensions.getStrings())
2537 {
2538 mExtensionStrings.push_back(MakeStaticString(extensionString));
2539 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002540 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002541
Bryan Bernhart58806562017-01-05 13:09:31 -08002542 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2543
Geoff Langc339c4e2016-11-29 10:37:36 -05002544 mRequestableExtensionStrings.clear();
2545 for (const auto &extensionInfo : GetExtensionInfoMap())
2546 {
2547 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002548 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2549 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002550 {
2551 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2552 }
2553 }
2554 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002555}
2556
Geoff Langc339c4e2016-11-29 10:37:36 -05002557const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002558{
Geoff Langc339c4e2016-11-29 10:37:36 -05002559 switch (name)
2560 {
2561 case GL_VENDOR:
2562 return reinterpret_cast<const GLubyte *>("Google Inc.");
2563
2564 case GL_RENDERER:
2565 return reinterpret_cast<const GLubyte *>(mRendererString);
2566
2567 case GL_VERSION:
2568 return reinterpret_cast<const GLubyte *>(mVersionString);
2569
2570 case GL_SHADING_LANGUAGE_VERSION:
2571 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2572
2573 case GL_EXTENSIONS:
2574 return reinterpret_cast<const GLubyte *>(mExtensionString);
2575
2576 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2577 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2578
2579 default:
2580 UNREACHABLE();
2581 return nullptr;
2582 }
Geoff Langcec35902014-04-16 10:52:36 -04002583}
2584
Geoff Langc339c4e2016-11-29 10:37:36 -05002585const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002586{
Geoff Langc339c4e2016-11-29 10:37:36 -05002587 switch (name)
2588 {
2589 case GL_EXTENSIONS:
2590 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2591
2592 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2593 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2594
2595 default:
2596 UNREACHABLE();
2597 return nullptr;
2598 }
Geoff Langcec35902014-04-16 10:52:36 -04002599}
2600
2601size_t Context::getExtensionStringCount() const
2602{
2603 return mExtensionStrings.size();
2604}
2605
Geoff Langc339c4e2016-11-29 10:37:36 -05002606void Context::requestExtension(const char *name)
2607{
2608 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2609 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2610 const auto &extension = extensionInfos.at(name);
2611 ASSERT(extension.Requestable);
2612
2613 if (mExtensions.*(extension.ExtensionsMember))
2614 {
2615 // Extension already enabled
2616 return;
2617 }
2618
2619 mExtensions.*(extension.ExtensionsMember) = true;
2620 updateCaps();
2621 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002622
Jamie Madill2f348d22017-06-05 10:50:59 -04002623 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2624 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002625
2626 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2627 // formats renderable or sampleable.
2628 mState.mTextures->invalidateTextureComplenessCache();
2629 for (auto &zeroTexture : mZeroTextures)
2630 {
2631 zeroTexture.second->invalidateCompletenessCache();
2632 }
2633
2634 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002635}
2636
2637size_t Context::getRequestableExtensionStringCount() const
2638{
2639 return mRequestableExtensionStrings.size();
2640}
2641
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002642void Context::beginTransformFeedback(GLenum primitiveMode)
2643{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002644 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002645 ASSERT(transformFeedback != nullptr);
2646 ASSERT(!transformFeedback->isPaused());
2647
Jamie Madill6c1f6712017-02-14 19:08:04 -05002648 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002649}
2650
2651bool Context::hasActiveTransformFeedback(GLuint program) const
2652{
2653 for (auto pair : mTransformFeedbackMap)
2654 {
2655 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2656 {
2657 return true;
2658 }
2659 }
2660 return false;
2661}
2662
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002663void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002664{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002665 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002666
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002667 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002668
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002669 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002670
Geoff Langeb66a6e2016-10-31 13:06:12 -04002671 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002672 {
2673 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002674 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002675 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002676 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002677 mExtensions.multiview = false;
2678 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002679 }
2680
Geoff Langeb66a6e2016-10-31 13:06:12 -04002681 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002682 {
2683 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002684 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002685 }
2686
Jamie Madill00ed7a12016-05-19 13:13:38 -04002687 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002688 mExtensions.bindUniformLocation = true;
2689 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002690 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002691 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002692 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002693
2694 // Enable the no error extension if the context was created with the flag.
2695 mExtensions.noError = mSkipValidation;
2696
Corentin Wallezccab69d2017-01-27 16:57:15 -05002697 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002698 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002699
Geoff Lang70d0f492015-12-10 17:45:46 -05002700 // Explicitly enable GL_KHR_debug
2701 mExtensions.debug = true;
2702 mExtensions.maxDebugMessageLength = 1024;
2703 mExtensions.maxDebugLoggedMessages = 1024;
2704 mExtensions.maxDebugGroupStackDepth = 1024;
2705 mExtensions.maxLabelLength = 1024;
2706
Geoff Langff5b2d52016-09-07 11:32:23 -04002707 // Explicitly enable GL_ANGLE_robust_client_memory
2708 mExtensions.robustClientMemory = true;
2709
Jamie Madille08a1d32017-03-07 17:24:06 -05002710 // Determine robust resource init availability from EGL.
2711 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002712 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002713
Jamie Madillc43be722017-07-13 16:22:14 -04002714 // Enable the cache control query unconditionally.
2715 mExtensions.programCacheControl = true;
2716
Geoff Lang301d1612014-07-09 10:34:37 -04002717 // Apply implementation limits
2718 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002719 mCaps.maxVertexAttribBindings =
2720 getClientVersion() < ES_3_1
2721 ? mCaps.maxVertexAttributes
2722 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2723
Jamie Madill231c7f52017-04-26 13:45:37 -04002724 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2725 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2726 mCaps.maxVertexOutputComponents =
2727 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002728
Jamie Madill231c7f52017-04-26 13:45:37 -04002729 mCaps.maxFragmentInputComponents =
2730 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002731
Geoff Langc287ea62016-09-16 14:46:51 -04002732 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002733 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002734 for (const auto &extensionInfo : GetExtensionInfoMap())
2735 {
2736 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002737 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002738 {
2739 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2740 }
2741 }
2742
2743 // Generate texture caps
2744 updateCaps();
2745}
2746
2747void Context::updateCaps()
2748{
Geoff Lang900013c2014-07-07 11:32:19 -04002749 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002750 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002751
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002752 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002753 {
Geoff Langca271392017-04-05 12:30:00 -04002754 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002755 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002756
Geoff Langca271392017-04-05 12:30:00 -04002757 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002758
Geoff Lang0d8b7242015-09-09 14:56:53 -04002759 // Update the format caps based on the client version and extensions.
2760 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2761 // ES3.
2762 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002763 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002764 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002765 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002766 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002767 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002768
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002769 // OpenGL ES does not support multisampling with non-rendererable formats
2770 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002771 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002772 (getClientVersion() < ES_3_1 &&
2773 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002774 {
Geoff Langd87878e2014-09-19 15:42:59 -04002775 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002776 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002777 else
2778 {
2779 // We may have limited the max samples for some required renderbuffer formats due to
2780 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2781 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2782
2783 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2784 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2785 // exception of signed and unsigned integer formats."
2786 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2787 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2788 {
2789 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2790 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2791 }
2792
2793 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2794 if (getClientVersion() >= ES_3_1)
2795 {
2796 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2797 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2798 // the exception that the signed and unsigned integer formats are required only to
2799 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2800 // multisamples, which must be at least one."
2801 if (formatInfo.componentType == GL_INT ||
2802 formatInfo.componentType == GL_UNSIGNED_INT)
2803 {
2804 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2805 }
2806
2807 // GLES 3.1 section 19.3.1.
2808 if (formatCaps.texturable)
2809 {
2810 if (formatInfo.depthBits > 0)
2811 {
2812 mCaps.maxDepthTextureSamples =
2813 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2814 }
2815 else if (formatInfo.redBits > 0)
2816 {
2817 mCaps.maxColorTextureSamples =
2818 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2819 }
2820 }
2821 }
2822 }
Geoff Langd87878e2014-09-19 15:42:59 -04002823
2824 if (formatCaps.texturable && formatInfo.compressed)
2825 {
Geoff Langca271392017-04-05 12:30:00 -04002826 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002827 }
2828
Geoff Langca271392017-04-05 12:30:00 -04002829 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002830 }
Jamie Madill32447362017-06-28 14:53:52 -04002831
2832 // If program binary is disabled, blank out the memory cache pointer.
2833 if (!mImplementation->getNativeExtensions().getProgramBinary)
2834 {
2835 mMemoryProgramCache = nullptr;
2836 }
Geoff Lang493daf52014-07-03 13:38:44 -04002837}
2838
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002839void Context::initWorkarounds()
2840{
Jamie Madill761b02c2017-06-23 16:27:06 -04002841 // Apply back-end workarounds.
2842 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2843
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002844 // Lose the context upon out of memory error if the application is
2845 // expecting to watch for those events.
2846 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2847}
2848
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002849Error Context::prepareForDraw(GLenum drawMode)
Jamie Madillb6664922017-07-25 12:55:04 -04002850{
2851 syncRendererState();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002852
2853 InfoLog infoLog;
2854 Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
2855 mMemoryProgramCache, drawMode);
2856 if (err.isError())
2857 {
2858 WARN() << "Dynamic recompilation error log: " << infoLog.str();
2859 }
2860 return err;
Jamie Madillb6664922017-07-25 12:55:04 -04002861}
2862
Jamie Madill1b94d432015-08-07 13:23:23 -04002863void Context::syncRendererState()
2864{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002865 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002866 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002867 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002868 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002869}
2870
Jamie Madillad9f24e2016-02-12 09:27:24 -05002871void Context::syncRendererState(const State::DirtyBits &bitMask,
2872 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002873{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002874 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002875 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002876 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002877 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002878}
Jamie Madillc29968b2016-01-20 11:17:23 -05002879
2880void Context::blitFramebuffer(GLint srcX0,
2881 GLint srcY0,
2882 GLint srcX1,
2883 GLint srcY1,
2884 GLint dstX0,
2885 GLint dstY0,
2886 GLint dstX1,
2887 GLint dstY1,
2888 GLbitfield mask,
2889 GLenum filter)
2890{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002891 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002892 ASSERT(drawFramebuffer);
2893
2894 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2895 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2896
Jamie Madillad9f24e2016-02-12 09:27:24 -05002897 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002898
Jamie Madillc564c072017-06-01 12:45:42 -04002899 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002900}
Jamie Madillc29968b2016-01-20 11:17:23 -05002901
2902void Context::clear(GLbitfield mask)
2903{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002904 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002905 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002906}
2907
2908void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2909{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002910 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002911 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002912}
2913
2914void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2915{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002916 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002917 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002918}
2919
2920void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2921{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002922 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002923 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002924}
2925
2926void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2927{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002928 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002929 ASSERT(framebufferObject);
2930
2931 // If a buffer is not present, the clear has no effect
2932 if (framebufferObject->getDepthbuffer() == nullptr &&
2933 framebufferObject->getStencilbuffer() == nullptr)
2934 {
2935 return;
2936 }
2937
Jamie Madillad9f24e2016-02-12 09:27:24 -05002938 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002939 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002940}
2941
2942void Context::readPixels(GLint x,
2943 GLint y,
2944 GLsizei width,
2945 GLsizei height,
2946 GLenum format,
2947 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002948 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002949{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002950 if (width == 0 || height == 0)
2951 {
2952 return;
2953 }
2954
Jamie Madillad9f24e2016-02-12 09:27:24 -05002955 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002956
Jamie Madillb6664922017-07-25 12:55:04 -04002957 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2958 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002959
2960 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002961 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002962}
2963
2964void Context::copyTexImage2D(GLenum target,
2965 GLint level,
2966 GLenum internalformat,
2967 GLint x,
2968 GLint y,
2969 GLsizei width,
2970 GLsizei height,
2971 GLint border)
2972{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002973 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002974 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002975
Jamie Madillc29968b2016-01-20 11:17:23 -05002976 Rectangle sourceArea(x, y, width, height);
2977
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002978 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002979 Texture *texture =
2980 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002981 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002982}
2983
2984void Context::copyTexSubImage2D(GLenum target,
2985 GLint level,
2986 GLint xoffset,
2987 GLint yoffset,
2988 GLint x,
2989 GLint y,
2990 GLsizei width,
2991 GLsizei height)
2992{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002993 if (width == 0 || height == 0)
2994 {
2995 return;
2996 }
2997
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002998 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002999 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003000
Jamie Madillc29968b2016-01-20 11:17:23 -05003001 Offset destOffset(xoffset, yoffset, 0);
3002 Rectangle sourceArea(x, y, width, height);
3003
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003004 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003005 Texture *texture =
3006 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003007 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05003008}
3009
3010void Context::copyTexSubImage3D(GLenum target,
3011 GLint level,
3012 GLint xoffset,
3013 GLint yoffset,
3014 GLint zoffset,
3015 GLint x,
3016 GLint y,
3017 GLsizei width,
3018 GLsizei height)
3019{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04003020 if (width == 0 || height == 0)
3021 {
3022 return;
3023 }
3024
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003025 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003026 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003027
Jamie Madillc29968b2016-01-20 11:17:23 -05003028 Offset destOffset(xoffset, yoffset, zoffset);
3029 Rectangle sourceArea(x, y, width, height);
3030
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003031 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003032 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003033 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05003034}
3035
3036void Context::framebufferTexture2D(GLenum target,
3037 GLenum attachment,
3038 GLenum textarget,
3039 GLuint texture,
3040 GLint level)
3041{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003042 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003043 ASSERT(framebuffer);
3044
3045 if (texture != 0)
3046 {
3047 Texture *textureObj = getTexture(texture);
3048
3049 ImageIndex index = ImageIndex::MakeInvalid();
3050
3051 if (textarget == GL_TEXTURE_2D)
3052 {
3053 index = ImageIndex::Make2D(level);
3054 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003055 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
3056 {
3057 index = ImageIndex::MakeRectangle(level);
3058 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08003059 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
3060 {
3061 ASSERT(level == 0);
3062 index = ImageIndex::Make2DMultisample();
3063 }
Jamie Madillc29968b2016-01-20 11:17:23 -05003064 else
3065 {
3066 ASSERT(IsCubeMapTextureTarget(textarget));
3067 index = ImageIndex::MakeCube(textarget, level);
3068 }
3069
Jamie Madilla02315b2017-02-23 14:14:47 -05003070 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05003071 }
3072 else
3073 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003074 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003075 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003076
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003077 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003078}
3079
3080void Context::framebufferRenderbuffer(GLenum target,
3081 GLenum attachment,
3082 GLenum renderbuffertarget,
3083 GLuint renderbuffer)
3084{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003085 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003086 ASSERT(framebuffer);
3087
3088 if (renderbuffer != 0)
3089 {
3090 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05003091
3092 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05003093 renderbufferObject);
3094 }
3095 else
3096 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003097 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003098 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003099
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003100 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003101}
3102
3103void Context::framebufferTextureLayer(GLenum target,
3104 GLenum attachment,
3105 GLuint texture,
3106 GLint level,
3107 GLint layer)
3108{
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 if (texture != 0)
3113 {
3114 Texture *textureObject = getTexture(texture);
3115
3116 ImageIndex index = ImageIndex::MakeInvalid();
3117
3118 if (textureObject->getTarget() == GL_TEXTURE_3D)
3119 {
3120 index = ImageIndex::Make3D(level, layer);
3121 }
3122 else
3123 {
3124 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3125 index = ImageIndex::Make2DArray(level, layer);
3126 }
3127
Jamie Madilla02315b2017-02-23 14:14:47 -05003128 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003129 }
3130 else
3131 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003132 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003133 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003134
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003135 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003136}
3137
Martin Radev137032d2017-07-13 10:11:12 +03003138void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3139 GLenum attachment,
3140 GLuint texture,
3141 GLint level,
3142 GLint baseViewIndex,
3143 GLsizei numViews)
3144{
3145 UNIMPLEMENTED();
3146}
3147
3148void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3149 GLenum attachment,
3150 GLuint texture,
3151 GLint level,
3152 GLsizei numViews,
3153 const GLint *viewportOffsets)
3154{
Martin Radev5dae57b2017-07-14 16:15:55 +03003155 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3156 ASSERT(framebuffer);
3157
3158 if (texture != 0)
3159 {
3160 Texture *textureObj = getTexture(texture);
3161
3162 ImageIndex index = ImageIndex::Make2D(level);
3163 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3164 textureObj, numViews, viewportOffsets);
3165 }
3166 else
3167 {
3168 framebuffer->resetAttachment(this, attachment);
3169 }
3170
3171 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003172}
3173
Jamie Madillc29968b2016-01-20 11:17:23 -05003174void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3175{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003176 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003177 ASSERT(framebuffer);
3178 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003179 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003180}
3181
3182void Context::readBuffer(GLenum mode)
3183{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003184 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003185 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003186 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003187}
3188
3189void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3190{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003191 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003192 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003193
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003194 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003195 ASSERT(framebuffer);
3196
3197 // The specification isn't clear what should be done when the framebuffer isn't complete.
3198 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003199 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003200}
3201
3202void Context::invalidateFramebuffer(GLenum target,
3203 GLsizei numAttachments,
3204 const GLenum *attachments)
3205{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003206 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003207 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003208
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003209 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003210 ASSERT(framebuffer);
3211
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003212 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003213 {
Jamie Madill437fa652016-05-03 15:13:24 -04003214 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003215 }
Jamie Madill437fa652016-05-03 15:13:24 -04003216
Jamie Madill4928b7c2017-06-20 12:57:39 -04003217 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003218}
3219
3220void Context::invalidateSubFramebuffer(GLenum target,
3221 GLsizei numAttachments,
3222 const GLenum *attachments,
3223 GLint x,
3224 GLint y,
3225 GLsizei width,
3226 GLsizei height)
3227{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003228 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003229 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003230
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003231 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003232 ASSERT(framebuffer);
3233
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003234 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003235 {
Jamie Madill437fa652016-05-03 15:13:24 -04003236 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003237 }
Jamie Madill437fa652016-05-03 15:13:24 -04003238
3239 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003240 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003241}
3242
Jamie Madill73a84962016-02-12 09:27:23 -05003243void Context::texImage2D(GLenum target,
3244 GLint level,
3245 GLint internalformat,
3246 GLsizei width,
3247 GLsizei height,
3248 GLint border,
3249 GLenum format,
3250 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003251 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003252{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003253 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003254
3255 Extents size(width, height, 1);
3256 Texture *texture =
3257 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003258 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3259 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003260}
3261
3262void Context::texImage3D(GLenum target,
3263 GLint level,
3264 GLint internalformat,
3265 GLsizei width,
3266 GLsizei height,
3267 GLsizei depth,
3268 GLint border,
3269 GLenum format,
3270 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003271 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003272{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003273 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003274
3275 Extents size(width, height, depth);
3276 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003277 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3278 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003279}
3280
3281void Context::texSubImage2D(GLenum target,
3282 GLint level,
3283 GLint xoffset,
3284 GLint yoffset,
3285 GLsizei width,
3286 GLsizei height,
3287 GLenum format,
3288 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003289 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003290{
3291 // Zero sized uploads are valid but no-ops
3292 if (width == 0 || height == 0)
3293 {
3294 return;
3295 }
3296
Jamie Madillad9f24e2016-02-12 09:27:24 -05003297 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003298
3299 Box area(xoffset, yoffset, 0, width, height, 1);
3300 Texture *texture =
3301 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003302 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3303 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003304}
3305
3306void Context::texSubImage3D(GLenum target,
3307 GLint level,
3308 GLint xoffset,
3309 GLint yoffset,
3310 GLint zoffset,
3311 GLsizei width,
3312 GLsizei height,
3313 GLsizei depth,
3314 GLenum format,
3315 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003316 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003317{
3318 // Zero sized uploads are valid but no-ops
3319 if (width == 0 || height == 0 || depth == 0)
3320 {
3321 return;
3322 }
3323
Jamie Madillad9f24e2016-02-12 09:27:24 -05003324 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003325
3326 Box area(xoffset, yoffset, zoffset, width, height, depth);
3327 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003328 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3329 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003330}
3331
3332void Context::compressedTexImage2D(GLenum target,
3333 GLint level,
3334 GLenum internalformat,
3335 GLsizei width,
3336 GLsizei height,
3337 GLint border,
3338 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003339 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003340{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003341 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003342
3343 Extents size(width, height, 1);
3344 Texture *texture =
3345 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003346 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003347 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003348 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003349}
3350
3351void Context::compressedTexImage3D(GLenum target,
3352 GLint level,
3353 GLenum internalformat,
3354 GLsizei width,
3355 GLsizei height,
3356 GLsizei depth,
3357 GLint border,
3358 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003359 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003360{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003361 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003362
3363 Extents size(width, height, depth);
3364 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003365 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003366 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003367 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003368}
3369
3370void Context::compressedTexSubImage2D(GLenum target,
3371 GLint level,
3372 GLint xoffset,
3373 GLint yoffset,
3374 GLsizei width,
3375 GLsizei height,
3376 GLenum format,
3377 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003378 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003379{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003380 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003381
3382 Box area(xoffset, yoffset, 0, width, height, 1);
3383 Texture *texture =
3384 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003385 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003386 format, imageSize,
3387 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003388}
3389
3390void Context::compressedTexSubImage3D(GLenum target,
3391 GLint level,
3392 GLint xoffset,
3393 GLint yoffset,
3394 GLint zoffset,
3395 GLsizei width,
3396 GLsizei height,
3397 GLsizei depth,
3398 GLenum format,
3399 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003400 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003401{
3402 // Zero sized uploads are valid but no-ops
3403 if (width == 0 || height == 0)
3404 {
3405 return;
3406 }
3407
Jamie Madillad9f24e2016-02-12 09:27:24 -05003408 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003409
3410 Box area(xoffset, yoffset, zoffset, width, height, depth);
3411 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003412 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 format, imageSize,
3414 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003415}
3416
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003417void Context::generateMipmap(GLenum target)
3418{
3419 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003420 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003421}
3422
Geoff Lang97073d12016-04-20 10:42:34 -07003423void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003424 GLint sourceLevel,
3425 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003426 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003427 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003428 GLint internalFormat,
3429 GLenum destType,
3430 GLboolean unpackFlipY,
3431 GLboolean unpackPremultiplyAlpha,
3432 GLboolean unpackUnmultiplyAlpha)
3433{
3434 syncStateForTexImage();
3435
3436 gl::Texture *sourceTexture = getTexture(sourceId);
3437 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003438 handleError(destTexture->copyTexture(
3439 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3440 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003441}
3442
3443void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003444 GLint sourceLevel,
3445 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003446 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003447 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003448 GLint xoffset,
3449 GLint yoffset,
3450 GLint x,
3451 GLint y,
3452 GLsizei width,
3453 GLsizei height,
3454 GLboolean unpackFlipY,
3455 GLboolean unpackPremultiplyAlpha,
3456 GLboolean unpackUnmultiplyAlpha)
3457{
3458 // Zero sized copies are valid but no-ops
3459 if (width == 0 || height == 0)
3460 {
3461 return;
3462 }
3463
3464 syncStateForTexImage();
3465
3466 gl::Texture *sourceTexture = getTexture(sourceId);
3467 gl::Texture *destTexture = getTexture(destId);
3468 Offset offset(xoffset, yoffset, 0);
3469 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003470 handleError(destTexture->copySubTexture(
3471 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3472 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003473}
3474
Geoff Lang47110bf2016-04-20 11:13:22 -07003475void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3476{
3477 syncStateForTexImage();
3478
3479 gl::Texture *sourceTexture = getTexture(sourceId);
3480 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003481 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003482}
3483
Geoff Lang496c02d2016-10-20 11:38:11 -07003484void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003485{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003486 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003487 ASSERT(buffer);
3488
Geoff Lang496c02d2016-10-20 11:38:11 -07003489 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003490}
3491
Jamie Madill876429b2017-04-20 15:46:24 -04003492void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003493{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003494 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003495 ASSERT(buffer);
3496
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003497 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003498 if (error.isError())
3499 {
Jamie Madill437fa652016-05-03 15:13:24 -04003500 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003501 return nullptr;
3502 }
3503
3504 return buffer->getMapPointer();
3505}
3506
3507GLboolean Context::unmapBuffer(GLenum target)
3508{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003509 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003510 ASSERT(buffer);
3511
3512 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003513 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003514 if (error.isError())
3515 {
Jamie Madill437fa652016-05-03 15:13:24 -04003516 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003517 return GL_FALSE;
3518 }
3519
3520 return result;
3521}
3522
Jamie Madill876429b2017-04-20 15:46:24 -04003523void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003524{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003526 ASSERT(buffer);
3527
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003528 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003529 if (error.isError())
3530 {
Jamie Madill437fa652016-05-03 15:13:24 -04003531 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003532 return nullptr;
3533 }
3534
3535 return buffer->getMapPointer();
3536}
3537
3538void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3539{
3540 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3541}
3542
Jamie Madillad9f24e2016-02-12 09:27:24 -05003543void Context::syncStateForReadPixels()
3544{
3545 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3546}
3547
3548void Context::syncStateForTexImage()
3549{
3550 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3551}
3552
3553void Context::syncStateForClear()
3554{
3555 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3556}
3557
3558void Context::syncStateForBlit()
3559{
3560 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3561}
3562
Jamie Madillc20ab272016-06-09 07:20:46 -07003563void Context::activeTexture(GLenum texture)
3564{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003565 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003566}
3567
Jamie Madill876429b2017-04-20 15:46:24 -04003568void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003569{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003570 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003571}
3572
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003573void Context::blendEquation(GLenum mode)
3574{
3575 mGLState.setBlendEquation(mode, mode);
3576}
3577
Jamie Madillc20ab272016-06-09 07:20:46 -07003578void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3579{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003580 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003581}
3582
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003583void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3584{
3585 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3586}
3587
Jamie Madillc20ab272016-06-09 07:20:46 -07003588void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3589{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003590 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003591}
3592
Jamie Madill876429b2017-04-20 15:46:24 -04003593void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003594{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003595 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003596}
3597
Jamie Madill876429b2017-04-20 15:46:24 -04003598void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003599{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003600 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003601}
3602
3603void Context::clearStencil(GLint s)
3604{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003605 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003606}
3607
3608void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3609{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003610 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003611}
3612
3613void Context::cullFace(GLenum mode)
3614{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003615 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003616}
3617
3618void Context::depthFunc(GLenum func)
3619{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003620 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003621}
3622
3623void Context::depthMask(GLboolean flag)
3624{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003625 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003626}
3627
Jamie Madill876429b2017-04-20 15:46:24 -04003628void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003629{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003630 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003631}
3632
3633void Context::disable(GLenum cap)
3634{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003635 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003636}
3637
3638void Context::disableVertexAttribArray(GLuint index)
3639{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003640 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003641}
3642
3643void Context::enable(GLenum cap)
3644{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003645 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003646}
3647
3648void Context::enableVertexAttribArray(GLuint index)
3649{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003650 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003651}
3652
3653void Context::frontFace(GLenum mode)
3654{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003655 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003656}
3657
3658void Context::hint(GLenum target, GLenum mode)
3659{
3660 switch (target)
3661 {
3662 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003663 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003664 break;
3665
3666 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003667 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003668 break;
3669
3670 default:
3671 UNREACHABLE();
3672 return;
3673 }
3674}
3675
3676void Context::lineWidth(GLfloat width)
3677{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003678 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003679}
3680
3681void Context::pixelStorei(GLenum pname, GLint param)
3682{
3683 switch (pname)
3684 {
3685 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003686 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003687 break;
3688
3689 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003690 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003691 break;
3692
3693 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003694 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003695 break;
3696
3697 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003698 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003699 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003700 break;
3701
3702 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003703 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003704 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003705 break;
3706
3707 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003708 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003709 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003710 break;
3711
3712 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003713 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003714 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003715 break;
3716
3717 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003718 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003719 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003720 break;
3721
3722 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003723 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003724 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003725 break;
3726
3727 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003728 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003729 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003730 break;
3731
3732 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003733 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003734 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003735 break;
3736
3737 default:
3738 UNREACHABLE();
3739 return;
3740 }
3741}
3742
3743void Context::polygonOffset(GLfloat factor, GLfloat units)
3744{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003745 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003746}
3747
Jamie Madill876429b2017-04-20 15:46:24 -04003748void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003749{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003750 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003751}
3752
3753void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3754{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003755 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003756}
3757
3758void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3759{
3760 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3761 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003762 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003763 }
3764
3765 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3766 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003767 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003768 }
3769}
3770
3771void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3772{
3773 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3774 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003775 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003776 }
3777
3778 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3779 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003780 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003781 }
3782}
3783
3784void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3785{
3786 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3787 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003788 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003789 }
3790
3791 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3792 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003793 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003794 }
3795}
3796
3797void Context::vertexAttrib1f(GLuint index, GLfloat x)
3798{
3799 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003800 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003801}
3802
3803void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3804{
3805 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003806 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003807}
3808
3809void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3810{
3811 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003812 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003813}
3814
3815void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3816{
3817 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003818 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003819}
3820
3821void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3822{
3823 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003824 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003825}
3826
3827void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3828{
3829 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003830 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003831}
3832
3833void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3834{
3835 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003836 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003837}
3838
3839void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3840{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003841 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003842}
3843
3844void Context::vertexAttribPointer(GLuint index,
3845 GLint size,
3846 GLenum type,
3847 GLboolean normalized,
3848 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003849 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003850{
Shaodde78e82017-05-22 14:13:27 +08003851 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3852 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003853}
3854
Shao80957d92017-02-20 21:25:59 +08003855void Context::vertexAttribFormat(GLuint attribIndex,
3856 GLint size,
3857 GLenum type,
3858 GLboolean normalized,
3859 GLuint relativeOffset)
3860{
3861 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3862 relativeOffset);
3863}
3864
3865void Context::vertexAttribIFormat(GLuint attribIndex,
3866 GLint size,
3867 GLenum type,
3868 GLuint relativeOffset)
3869{
3870 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3871}
3872
3873void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3874{
Shaodde78e82017-05-22 14:13:27 +08003875 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003876}
3877
3878void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3879{
3880 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3881}
3882
Jamie Madillc20ab272016-06-09 07:20:46 -07003883void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3884{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003885 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003886}
3887
3888void Context::vertexAttribIPointer(GLuint index,
3889 GLint size,
3890 GLenum type,
3891 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003892 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003893{
Shaodde78e82017-05-22 14:13:27 +08003894 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3895 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003896}
3897
3898void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3899{
3900 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003901 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003902}
3903
3904void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3905{
3906 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003907 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003908}
3909
3910void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3911{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003912 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003913}
3914
3915void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3916{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003917 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003918}
3919
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003920void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3921{
3922 const VertexAttribCurrentValueData &currentValues =
3923 getGLState().getVertexAttribCurrentValue(index);
3924 const VertexArray *vao = getGLState().getVertexArray();
3925 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3926 currentValues, pname, params);
3927}
3928
3929void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3930{
3931 const VertexAttribCurrentValueData &currentValues =
3932 getGLState().getVertexAttribCurrentValue(index);
3933 const VertexArray *vao = getGLState().getVertexArray();
3934 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3935 currentValues, pname, params);
3936}
3937
3938void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3939{
3940 const VertexAttribCurrentValueData &currentValues =
3941 getGLState().getVertexAttribCurrentValue(index);
3942 const VertexArray *vao = getGLState().getVertexArray();
3943 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3944 currentValues, pname, params);
3945}
3946
3947void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3948{
3949 const VertexAttribCurrentValueData &currentValues =
3950 getGLState().getVertexAttribCurrentValue(index);
3951 const VertexArray *vao = getGLState().getVertexArray();
3952 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3953 currentValues, pname, params);
3954}
3955
Jamie Madill876429b2017-04-20 15:46:24 -04003956void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003957{
3958 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3959 QueryVertexAttribPointerv(attrib, pname, pointer);
3960}
3961
Jamie Madillc20ab272016-06-09 07:20:46 -07003962void Context::debugMessageControl(GLenum source,
3963 GLenum type,
3964 GLenum severity,
3965 GLsizei count,
3966 const GLuint *ids,
3967 GLboolean enabled)
3968{
3969 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003970 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3971 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003972}
3973
3974void Context::debugMessageInsert(GLenum source,
3975 GLenum type,
3976 GLuint id,
3977 GLenum severity,
3978 GLsizei length,
3979 const GLchar *buf)
3980{
3981 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003982 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003983}
3984
3985void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3986{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003987 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003988}
3989
3990GLuint Context::getDebugMessageLog(GLuint count,
3991 GLsizei bufSize,
3992 GLenum *sources,
3993 GLenum *types,
3994 GLuint *ids,
3995 GLenum *severities,
3996 GLsizei *lengths,
3997 GLchar *messageLog)
3998{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003999 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
4000 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07004001}
4002
4003void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
4004{
4005 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07004006 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07004007}
4008
4009void Context::popDebugGroup()
4010{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07004011 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07004012}
4013
Jamie Madill876429b2017-04-20 15:46:24 -04004014void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04004015{
4016 Buffer *buffer = mGLState.getTargetBuffer(target);
4017 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08004018 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04004019}
4020
Jamie Madill876429b2017-04-20 15:46:24 -04004021void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004022{
4023 if (data == nullptr)
4024 {
4025 return;
4026 }
4027
4028 Buffer *buffer = mGLState.getTargetBuffer(target);
4029 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08004030 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04004031}
4032
Jamie Madillef300b12016-10-07 15:12:09 -04004033void Context::attachShader(GLuint program, GLuint shader)
4034{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004035 auto programObject = mState.mShaderPrograms->getProgram(program);
4036 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04004037 ASSERT(programObject && shaderObject);
4038 programObject->attachShader(shaderObject);
4039}
4040
Kenneth Russellf2f6f652016-10-05 19:53:23 -07004041const Workarounds &Context::getWorkarounds() const
4042{
4043 return mWorkarounds;
4044}
4045
Jamie Madillb0817d12016-11-01 15:48:31 -04004046void Context::copyBufferSubData(GLenum readTarget,
4047 GLenum writeTarget,
4048 GLintptr readOffset,
4049 GLintptr writeOffset,
4050 GLsizeiptr size)
4051{
4052 // if size is zero, the copy is a successful no-op
4053 if (size == 0)
4054 {
4055 return;
4056 }
4057
4058 // TODO(jmadill): cache these.
4059 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
4060 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
4061
Jamie Madill5f56ddb2017-01-13 17:29:55 -05004062 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04004063}
4064
Jamie Madill01a80ee2016-11-07 12:06:18 -05004065void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
4066{
4067 Program *programObject = getProgram(program);
4068 // TODO(jmadill): Re-use this from the validation if possible.
4069 ASSERT(programObject);
4070 programObject->bindAttributeLocation(index, name);
4071}
4072
4073void Context::bindBuffer(GLenum target, GLuint buffer)
4074{
4075 switch (target)
4076 {
4077 case GL_ARRAY_BUFFER:
4078 bindArrayBuffer(buffer);
4079 break;
4080 case GL_ELEMENT_ARRAY_BUFFER:
4081 bindElementArrayBuffer(buffer);
4082 break;
4083 case GL_COPY_READ_BUFFER:
4084 bindCopyReadBuffer(buffer);
4085 break;
4086 case GL_COPY_WRITE_BUFFER:
4087 bindCopyWriteBuffer(buffer);
4088 break;
4089 case GL_PIXEL_PACK_BUFFER:
4090 bindPixelPackBuffer(buffer);
4091 break;
4092 case GL_PIXEL_UNPACK_BUFFER:
4093 bindPixelUnpackBuffer(buffer);
4094 break;
4095 case GL_UNIFORM_BUFFER:
4096 bindGenericUniformBuffer(buffer);
4097 break;
4098 case GL_TRANSFORM_FEEDBACK_BUFFER:
4099 bindGenericTransformFeedbackBuffer(buffer);
4100 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004101 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004102 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004103 break;
4104 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004105 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004106 break;
4107 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004108 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004109 break;
4110 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004111 if (buffer != 0)
4112 {
4113 // Binding buffers to this binding point is not implemented yet.
4114 UNIMPLEMENTED();
4115 }
Geoff Lang3b573612016-10-31 14:08:10 -04004116 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004117
4118 default:
4119 UNREACHABLE();
4120 break;
4121 }
4122}
4123
Jiajia Qin6eafb042016-12-27 17:04:07 +08004124void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4125{
4126 bindBufferRange(target, index, buffer, 0, 0);
4127}
4128
4129void Context::bindBufferRange(GLenum target,
4130 GLuint index,
4131 GLuint buffer,
4132 GLintptr offset,
4133 GLsizeiptr size)
4134{
4135 switch (target)
4136 {
4137 case GL_TRANSFORM_FEEDBACK_BUFFER:
4138 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4139 bindGenericTransformFeedbackBuffer(buffer);
4140 break;
4141 case GL_UNIFORM_BUFFER:
4142 bindIndexedUniformBuffer(buffer, index, offset, size);
4143 bindGenericUniformBuffer(buffer);
4144 break;
4145 case GL_ATOMIC_COUNTER_BUFFER:
4146 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4147 bindGenericAtomicCounterBuffer(buffer);
4148 break;
4149 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004150 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4151 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004152 break;
4153 default:
4154 UNREACHABLE();
4155 break;
4156 }
4157}
4158
Jamie Madill01a80ee2016-11-07 12:06:18 -05004159void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4160{
4161 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4162 {
4163 bindReadFramebuffer(framebuffer);
4164 }
4165
4166 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4167 {
4168 bindDrawFramebuffer(framebuffer);
4169 }
4170}
4171
4172void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4173{
4174 ASSERT(target == GL_RENDERBUFFER);
4175 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004176 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004177 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004178}
4179
JiangYizhoubddc46b2016-12-09 09:50:51 +08004180void Context::texStorage2DMultisample(GLenum target,
4181 GLsizei samples,
4182 GLenum internalformat,
4183 GLsizei width,
4184 GLsizei height,
4185 GLboolean fixedsamplelocations)
4186{
4187 Extents size(width, height, 1);
4188 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004189 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004190 fixedsamplelocations));
4191}
4192
4193void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4194{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004195 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004196 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4197
4198 switch (pname)
4199 {
4200 case GL_SAMPLE_POSITION:
4201 handleError(framebuffer->getSamplePosition(index, val));
4202 break;
4203 default:
4204 UNREACHABLE();
4205 }
4206}
4207
Jamie Madille8fb6402017-02-14 17:56:40 -05004208void Context::renderbufferStorage(GLenum target,
4209 GLenum internalformat,
4210 GLsizei width,
4211 GLsizei height)
4212{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004213 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4214 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4215
Jamie Madille8fb6402017-02-14 17:56:40 -05004216 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004217 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004218}
4219
4220void Context::renderbufferStorageMultisample(GLenum target,
4221 GLsizei samples,
4222 GLenum internalformat,
4223 GLsizei width,
4224 GLsizei height)
4225{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004226 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4227 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004228
4229 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004230 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004231 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004232}
4233
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004234void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4235{
4236 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004237 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004238}
4239
JiangYizhoue18e6392017-02-20 10:32:23 +08004240void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4241{
4242 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4243 QueryFramebufferParameteriv(framebuffer, pname, params);
4244}
4245
4246void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4247{
4248 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4249 SetFramebufferParameteri(framebuffer, pname, param);
4250}
4251
Jamie Madillb3f26b92017-07-19 15:07:41 -04004252Error Context::getScratchBuffer(size_t requstedSizeBytes,
4253 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004254{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004255 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4256 {
4257 return OutOfMemory() << "Failed to allocate internal buffer.";
4258 }
4259 return NoError();
4260}
4261
4262Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4263 angle::MemoryBuffer **zeroBufferOut) const
4264{
4265 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004266 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004267 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004268 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004269 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004270}
4271
Xinghua Cao2b396592017-03-29 15:36:04 +08004272void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4273{
4274 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4275 {
4276 return;
4277 }
4278
Jamie Madillfe548342017-06-19 11:13:24 -04004279 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004280}
4281
JiangYizhou165361c2017-06-07 14:56:57 +08004282void Context::texStorage2D(GLenum target,
4283 GLsizei levels,
4284 GLenum internalFormat,
4285 GLsizei width,
4286 GLsizei height)
4287{
4288 Extents size(width, height, 1);
4289 Texture *texture = getTargetTexture(target);
4290 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4291}
4292
4293void Context::texStorage3D(GLenum target,
4294 GLsizei levels,
4295 GLenum internalFormat,
4296 GLsizei width,
4297 GLsizei height,
4298 GLsizei depth)
4299{
4300 Extents size(width, height, depth);
4301 Texture *texture = getTargetTexture(target);
4302 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4303}
4304
Jamie Madillc1d770e2017-04-13 17:31:24 -04004305GLenum Context::checkFramebufferStatus(GLenum target)
4306{
4307 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4308 ASSERT(framebuffer);
4309
4310 return framebuffer->checkStatus(this);
4311}
4312
4313void Context::compileShader(GLuint shader)
4314{
4315 Shader *shaderObject = GetValidShader(this, shader);
4316 if (!shaderObject)
4317 {
4318 return;
4319 }
4320 shaderObject->compile(this);
4321}
4322
4323void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4324{
4325 for (int i = 0; i < n; i++)
4326 {
4327 deleteBuffer(buffers[i]);
4328 }
4329}
4330
4331void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4332{
4333 for (int i = 0; i < n; i++)
4334 {
4335 if (framebuffers[i] != 0)
4336 {
4337 deleteFramebuffer(framebuffers[i]);
4338 }
4339 }
4340}
4341
4342void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4343{
4344 for (int i = 0; i < n; i++)
4345 {
4346 deleteRenderbuffer(renderbuffers[i]);
4347 }
4348}
4349
4350void Context::deleteTextures(GLsizei n, const GLuint *textures)
4351{
4352 for (int i = 0; i < n; i++)
4353 {
4354 if (textures[i] != 0)
4355 {
4356 deleteTexture(textures[i]);
4357 }
4358 }
4359}
4360
4361void Context::detachShader(GLuint program, GLuint shader)
4362{
4363 Program *programObject = getProgram(program);
4364 ASSERT(programObject);
4365
4366 Shader *shaderObject = getShader(shader);
4367 ASSERT(shaderObject);
4368
4369 programObject->detachShader(this, shaderObject);
4370}
4371
4372void Context::genBuffers(GLsizei n, GLuint *buffers)
4373{
4374 for (int i = 0; i < n; i++)
4375 {
4376 buffers[i] = createBuffer();
4377 }
4378}
4379
4380void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4381{
4382 for (int i = 0; i < n; i++)
4383 {
4384 framebuffers[i] = createFramebuffer();
4385 }
4386}
4387
4388void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4389{
4390 for (int i = 0; i < n; i++)
4391 {
4392 renderbuffers[i] = createRenderbuffer();
4393 }
4394}
4395
4396void Context::genTextures(GLsizei n, GLuint *textures)
4397{
4398 for (int i = 0; i < n; i++)
4399 {
4400 textures[i] = createTexture();
4401 }
4402}
4403
4404void Context::getActiveAttrib(GLuint program,
4405 GLuint index,
4406 GLsizei bufsize,
4407 GLsizei *length,
4408 GLint *size,
4409 GLenum *type,
4410 GLchar *name)
4411{
4412 Program *programObject = getProgram(program);
4413 ASSERT(programObject);
4414 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4415}
4416
4417void Context::getActiveUniform(GLuint program,
4418 GLuint index,
4419 GLsizei bufsize,
4420 GLsizei *length,
4421 GLint *size,
4422 GLenum *type,
4423 GLchar *name)
4424{
4425 Program *programObject = getProgram(program);
4426 ASSERT(programObject);
4427 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4428}
4429
4430void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4431{
4432 Program *programObject = getProgram(program);
4433 ASSERT(programObject);
4434 programObject->getAttachedShaders(maxcount, count, shaders);
4435}
4436
4437GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4438{
4439 Program *programObject = getProgram(program);
4440 ASSERT(programObject);
4441 return programObject->getAttributeLocation(name);
4442}
4443
4444void Context::getBooleanv(GLenum pname, GLboolean *params)
4445{
4446 GLenum nativeType;
4447 unsigned int numParams = 0;
4448 getQueryParameterInfo(pname, &nativeType, &numParams);
4449
4450 if (nativeType == GL_BOOL)
4451 {
4452 getBooleanvImpl(pname, params);
4453 }
4454 else
4455 {
4456 CastStateValues(this, nativeType, pname, numParams, params);
4457 }
4458}
4459
4460void Context::getFloatv(GLenum pname, GLfloat *params)
4461{
4462 GLenum nativeType;
4463 unsigned int numParams = 0;
4464 getQueryParameterInfo(pname, &nativeType, &numParams);
4465
4466 if (nativeType == GL_FLOAT)
4467 {
4468 getFloatvImpl(pname, params);
4469 }
4470 else
4471 {
4472 CastStateValues(this, nativeType, pname, numParams, params);
4473 }
4474}
4475
4476void Context::getIntegerv(GLenum pname, GLint *params)
4477{
4478 GLenum nativeType;
4479 unsigned int numParams = 0;
4480 getQueryParameterInfo(pname, &nativeType, &numParams);
4481
4482 if (nativeType == GL_INT)
4483 {
4484 getIntegervImpl(pname, params);
4485 }
4486 else
4487 {
4488 CastStateValues(this, nativeType, pname, numParams, params);
4489 }
4490}
4491
4492void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4493{
4494 Program *programObject = getProgram(program);
4495 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004496 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004497}
4498
Jamie Madillbe849e42017-05-02 15:49:00 -04004499void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004500{
4501 Program *programObject = getProgram(program);
4502 ASSERT(programObject);
4503 programObject->getInfoLog(bufsize, length, infolog);
4504}
4505
4506void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4507{
4508 Shader *shaderObject = getShader(shader);
4509 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004510 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004511}
4512
4513void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4514{
4515 Shader *shaderObject = getShader(shader);
4516 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004517 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004518}
4519
4520void Context::getShaderPrecisionFormat(GLenum shadertype,
4521 GLenum precisiontype,
4522 GLint *range,
4523 GLint *precision)
4524{
4525 // TODO(jmadill): Compute shaders.
4526
4527 switch (shadertype)
4528 {
4529 case GL_VERTEX_SHADER:
4530 switch (precisiontype)
4531 {
4532 case GL_LOW_FLOAT:
4533 mCaps.vertexLowpFloat.get(range, precision);
4534 break;
4535 case GL_MEDIUM_FLOAT:
4536 mCaps.vertexMediumpFloat.get(range, precision);
4537 break;
4538 case GL_HIGH_FLOAT:
4539 mCaps.vertexHighpFloat.get(range, precision);
4540 break;
4541
4542 case GL_LOW_INT:
4543 mCaps.vertexLowpInt.get(range, precision);
4544 break;
4545 case GL_MEDIUM_INT:
4546 mCaps.vertexMediumpInt.get(range, precision);
4547 break;
4548 case GL_HIGH_INT:
4549 mCaps.vertexHighpInt.get(range, precision);
4550 break;
4551
4552 default:
4553 UNREACHABLE();
4554 return;
4555 }
4556 break;
4557
4558 case GL_FRAGMENT_SHADER:
4559 switch (precisiontype)
4560 {
4561 case GL_LOW_FLOAT:
4562 mCaps.fragmentLowpFloat.get(range, precision);
4563 break;
4564 case GL_MEDIUM_FLOAT:
4565 mCaps.fragmentMediumpFloat.get(range, precision);
4566 break;
4567 case GL_HIGH_FLOAT:
4568 mCaps.fragmentHighpFloat.get(range, precision);
4569 break;
4570
4571 case GL_LOW_INT:
4572 mCaps.fragmentLowpInt.get(range, precision);
4573 break;
4574 case GL_MEDIUM_INT:
4575 mCaps.fragmentMediumpInt.get(range, precision);
4576 break;
4577 case GL_HIGH_INT:
4578 mCaps.fragmentHighpInt.get(range, precision);
4579 break;
4580
4581 default:
4582 UNREACHABLE();
4583 return;
4584 }
4585 break;
4586
4587 default:
4588 UNREACHABLE();
4589 return;
4590 }
4591}
4592
4593void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4594{
4595 Shader *shaderObject = getShader(shader);
4596 ASSERT(shaderObject);
4597 shaderObject->getSource(bufsize, length, source);
4598}
4599
4600void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4601{
4602 Program *programObject = getProgram(program);
4603 ASSERT(programObject);
4604 programObject->getUniformfv(location, params);
4605}
4606
4607void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4608{
4609 Program *programObject = getProgram(program);
4610 ASSERT(programObject);
4611 programObject->getUniformiv(location, params);
4612}
4613
4614GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4615{
4616 Program *programObject = getProgram(program);
4617 ASSERT(programObject);
4618 return programObject->getUniformLocation(name);
4619}
4620
4621GLboolean Context::isBuffer(GLuint buffer)
4622{
4623 if (buffer == 0)
4624 {
4625 return GL_FALSE;
4626 }
4627
4628 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4629}
4630
4631GLboolean Context::isEnabled(GLenum cap)
4632{
4633 return mGLState.getEnableFeature(cap);
4634}
4635
4636GLboolean Context::isFramebuffer(GLuint framebuffer)
4637{
4638 if (framebuffer == 0)
4639 {
4640 return GL_FALSE;
4641 }
4642
4643 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4644}
4645
4646GLboolean Context::isProgram(GLuint program)
4647{
4648 if (program == 0)
4649 {
4650 return GL_FALSE;
4651 }
4652
4653 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4654}
4655
4656GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4657{
4658 if (renderbuffer == 0)
4659 {
4660 return GL_FALSE;
4661 }
4662
4663 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4664}
4665
4666GLboolean Context::isShader(GLuint shader)
4667{
4668 if (shader == 0)
4669 {
4670 return GL_FALSE;
4671 }
4672
4673 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4674}
4675
4676GLboolean Context::isTexture(GLuint texture)
4677{
4678 if (texture == 0)
4679 {
4680 return GL_FALSE;
4681 }
4682
4683 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4684}
4685
4686void Context::linkProgram(GLuint program)
4687{
4688 Program *programObject = getProgram(program);
4689 ASSERT(programObject);
4690 handleError(programObject->link(this));
4691}
4692
4693void Context::releaseShaderCompiler()
4694{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004695 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004696}
4697
4698void Context::shaderBinary(GLsizei n,
4699 const GLuint *shaders,
4700 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004701 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004702 GLsizei length)
4703{
4704 // No binary shader formats are supported.
4705 UNIMPLEMENTED();
4706}
4707
4708void Context::shaderSource(GLuint shader,
4709 GLsizei count,
4710 const GLchar *const *string,
4711 const GLint *length)
4712{
4713 Shader *shaderObject = getShader(shader);
4714 ASSERT(shaderObject);
4715 shaderObject->setSource(count, string, length);
4716}
4717
4718void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4719{
4720 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4721}
4722
4723void Context::stencilMask(GLuint mask)
4724{
4725 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4726}
4727
4728void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4729{
4730 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4731}
4732
4733void Context::uniform1f(GLint location, GLfloat x)
4734{
4735 Program *program = mGLState.getProgram();
4736 program->setUniform1fv(location, 1, &x);
4737}
4738
4739void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4740{
4741 Program *program = mGLState.getProgram();
4742 program->setUniform1fv(location, count, v);
4743}
4744
4745void Context::uniform1i(GLint location, GLint x)
4746{
4747 Program *program = mGLState.getProgram();
4748 program->setUniform1iv(location, 1, &x);
4749}
4750
4751void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4752{
4753 Program *program = mGLState.getProgram();
4754 program->setUniform1iv(location, count, v);
4755}
4756
4757void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4758{
4759 GLfloat xy[2] = {x, y};
4760 Program *program = mGLState.getProgram();
4761 program->setUniform2fv(location, 1, xy);
4762}
4763
4764void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4765{
4766 Program *program = mGLState.getProgram();
4767 program->setUniform2fv(location, count, v);
4768}
4769
4770void Context::uniform2i(GLint location, GLint x, GLint y)
4771{
4772 GLint xy[2] = {x, y};
4773 Program *program = mGLState.getProgram();
4774 program->setUniform2iv(location, 1, xy);
4775}
4776
4777void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4778{
4779 Program *program = mGLState.getProgram();
4780 program->setUniform2iv(location, count, v);
4781}
4782
4783void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4784{
4785 GLfloat xyz[3] = {x, y, z};
4786 Program *program = mGLState.getProgram();
4787 program->setUniform3fv(location, 1, xyz);
4788}
4789
4790void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4791{
4792 Program *program = mGLState.getProgram();
4793 program->setUniform3fv(location, count, v);
4794}
4795
4796void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4797{
4798 GLint xyz[3] = {x, y, z};
4799 Program *program = mGLState.getProgram();
4800 program->setUniform3iv(location, 1, xyz);
4801}
4802
4803void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4804{
4805 Program *program = mGLState.getProgram();
4806 program->setUniform3iv(location, count, v);
4807}
4808
4809void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4810{
4811 GLfloat xyzw[4] = {x, y, z, w};
4812 Program *program = mGLState.getProgram();
4813 program->setUniform4fv(location, 1, xyzw);
4814}
4815
4816void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4817{
4818 Program *program = mGLState.getProgram();
4819 program->setUniform4fv(location, count, v);
4820}
4821
4822void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4823{
4824 GLint xyzw[4] = {x, y, z, w};
4825 Program *program = mGLState.getProgram();
4826 program->setUniform4iv(location, 1, xyzw);
4827}
4828
4829void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4830{
4831 Program *program = mGLState.getProgram();
4832 program->setUniform4iv(location, count, v);
4833}
4834
4835void Context::uniformMatrix2fv(GLint location,
4836 GLsizei count,
4837 GLboolean transpose,
4838 const GLfloat *value)
4839{
4840 Program *program = mGLState.getProgram();
4841 program->setUniformMatrix2fv(location, count, transpose, value);
4842}
4843
4844void Context::uniformMatrix3fv(GLint location,
4845 GLsizei count,
4846 GLboolean transpose,
4847 const GLfloat *value)
4848{
4849 Program *program = mGLState.getProgram();
4850 program->setUniformMatrix3fv(location, count, transpose, value);
4851}
4852
4853void Context::uniformMatrix4fv(GLint location,
4854 GLsizei count,
4855 GLboolean transpose,
4856 const GLfloat *value)
4857{
4858 Program *program = mGLState.getProgram();
4859 program->setUniformMatrix4fv(location, count, transpose, value);
4860}
4861
4862void Context::validateProgram(GLuint program)
4863{
4864 Program *programObject = getProgram(program);
4865 ASSERT(programObject);
4866 programObject->validate(mCaps);
4867}
4868
Jamie Madilld04908b2017-06-09 14:15:35 -04004869void Context::getProgramBinary(GLuint program,
4870 GLsizei bufSize,
4871 GLsizei *length,
4872 GLenum *binaryFormat,
4873 void *binary)
4874{
4875 Program *programObject = getProgram(program);
4876 ASSERT(programObject != nullptr);
4877
4878 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4879}
4880
4881void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4882{
4883 Program *programObject = getProgram(program);
4884 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004885
Jamie Madilld04908b2017-06-09 14:15:35 -04004886 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4887}
4888
Jamie Madillc29968b2016-01-20 11:17:23 -05004889} // namespace gl