blob: a7fb2b4477f20636ff11a5f0c11832d86734d906 [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
Ian Ewell3ffd78b2016-01-22 16:09:42 -050048template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050049std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030050 GLsizei numPaths,
51 const void *paths,
52 GLuint pathBase)
53{
54 std::vector<gl::Path *> ret;
55 ret.reserve(numPaths);
56
57 const auto *nameArray = static_cast<const T *>(paths);
58
59 for (GLsizei i = 0; i < numPaths; ++i)
60 {
61 const GLuint pathName = nameArray[i] + pathBase;
62
63 ret.push_back(resourceManager.getPath(pathName));
64 }
65
66 return ret;
67}
68
Geoff Lang4ddf5af2016-12-01 14:30:44 -050069std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030070 GLsizei numPaths,
71 GLenum pathNameType,
72 const void *paths,
73 GLuint pathBase)
74{
75 switch (pathNameType)
76 {
77 case GL_UNSIGNED_BYTE:
78 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_BYTE:
81 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_UNSIGNED_SHORT:
84 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_SHORT:
87 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_UNSIGNED_INT:
90 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
91
92 case GL_INT:
93 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
94 }
95
96 UNREACHABLE();
97 return std::vector<gl::Path *>();
98}
99
100template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400101gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500102{
Geoff Lang2186c382016-10-14 10:54:54 -0400103 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500104
105 switch (pname)
106 {
107 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400108 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109 case GL_QUERY_RESULT_AVAILABLE_EXT:
110 {
111 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400112 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500113 if (!error.isError())
114 {
Geoff Lang2186c382016-10-14 10:54:54 -0400115 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500116 }
117 return error;
118 }
119 default:
120 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500121 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500122 }
123}
124
Geoff Langf6db0982015-08-25 13:04:00 -0400125void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
126{
Geoff Lang1a683462015-09-29 15:09:59 -0400127 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400128 {
129 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
130 tfBufferIndex++)
131 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400132 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400133 transformFeedback->getIndexedBuffer(tfBufferIndex);
134 if (buffer.get() != nullptr)
135 {
136 buffer->onTransformFeedback();
137 }
138 }
139 }
140}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141
142// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300143EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400145 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146}
147
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
149{
150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
151}
152
Geoff Langeb66a6e2016-10-31 13:06:12 -0400153gl::Version GetClientVersion(const egl::AttributeMap &attribs)
154{
155 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
156}
157
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500158GLenum GetResetStrategy(const egl::AttributeMap &attribs)
159{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400160 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
161 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500162 switch (attrib)
163 {
164 case EGL_NO_RESET_NOTIFICATION:
165 return GL_NO_RESET_NOTIFICATION_EXT;
166 case EGL_LOSE_CONTEXT_ON_RESET:
167 return GL_LOSE_CONTEXT_ON_RESET_EXT;
168 default:
169 UNREACHABLE();
170 return GL_NONE;
171 }
172}
173
174bool GetRobustAccess(const egl::AttributeMap &attribs)
175{
Geoff Lang077f20a2016-11-01 10:08:02 -0400176 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
177 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
178 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500179}
180
181bool GetDebug(const egl::AttributeMap &attribs)
182{
Geoff Lang077f20a2016-11-01 10:08:02 -0400183 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
184 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500185}
186
187bool GetNoError(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
190}
191
Geoff Langc287ea62016-09-16 14:46:51 -0400192bool GetWebGLContext(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langf41a7152016-09-19 15:11:17 -0400197bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
200}
201
Geoff Langfeb8c682017-02-13 16:07:35 -0500202bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
205}
206
Martin Radev9d901792016-07-15 15:58:58 +0300207std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
208{
209 std::string labelName;
210 if (label != nullptr)
211 {
212 size_t labelLength = length < 0 ? strlen(label) : length;
213 labelName = std::string(label, labelLength);
214 }
215 return labelName;
216}
217
218void GetObjectLabelBase(const std::string &objectLabel,
219 GLsizei bufSize,
220 GLsizei *length,
221 GLchar *label)
222{
223 size_t writeLength = objectLabel.length();
224 if (label != nullptr && bufSize > 0)
225 {
226 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
227 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
228 label[writeLength] = '\0';
229 }
230
231 if (length != nullptr)
232 {
233 *length = static_cast<GLsizei>(writeLength);
234 }
235}
236
Geoff Langf6db0982015-08-25 13:04:00 -0400237} // anonymous namespace
238
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000239namespace gl
240{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000241
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400242Context::Context(rx::EGLImplFactory *implFactory,
243 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400244 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500245 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500246 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400247 const egl::DisplayExtensions &displayExtensions,
248 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300249
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500250 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500251 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500252 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700253 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500254 mCaps,
255 mTextureCaps,
256 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500257 mLimitations,
258 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700259 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400260 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400261 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500262 mClientType(EGL_OPENGL_ES_API),
263 mHasBeenCurrent(false),
264 mContextLost(false),
265 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700266 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500267 mResetStrategy(GetResetStrategy(attribs)),
268 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400269 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
270 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500271 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500272 mWebGLContext(GetWebGLContext(attribs)),
273 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000274{
Geoff Lang077f20a2016-11-01 10:08:02 -0400275 if (mRobustAccess)
276 {
277 UNIMPLEMENTED();
278 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000279
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500280 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700281 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400282
Jamie Madill4928b7c2017-06-20 12:57:39 -0400283 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
284 GetClientArraysEnabled(attribs), robustResourceInit);
Régis Fénéon83107972015-02-05 12:57:44 +0100285
Shannon Woods53a94a82014-06-24 15:20:36 -0400286 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400287
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000288 // [OpenGL ES 2.0.24] section 3.7 page 83:
289 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
290 // and cube map texture state vectors respectively associated with them.
291 // In order that access to these initial textures not be lost, they are treated as texture
292 // objects all of whose names are 0.
293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400295 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400298 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400299
Geoff Langeb66a6e2016-10-31 13:06:12 -0400300 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400301 {
302 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400304 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400305
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400307 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308 }
Geoff Lang3b573612016-10-31 14:08:10 -0400309 if (getClientVersion() >= Version(3, 1))
310 {
311 Texture *zeroTexture2DMultisample =
312 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400313 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800314
315 bindGenericAtomicCounterBuffer(0);
316 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
317 {
318 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
319 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800320
321 bindGenericShaderStorageBuffer(0);
322 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
323 {
324 bindIndexedShaderStorageBuffer(0, i, 0, 0);
325 }
Geoff Lang3b573612016-10-31 14:08:10 -0400326 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000327
Ian Ewellbda75592016-04-18 17:25:54 -0400328 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
329 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400330 Texture *zeroTextureExternal =
331 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400332 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400333 }
334
Jamie Madill4928b7c2017-06-20 12:57:39 -0400335 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500336
Jamie Madill57a89722013-07-02 11:57:03 -0400337 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000338 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800339 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000340 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400341
Jamie Madill01a80ee2016-11-07 12:06:18 -0500342 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000343
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000344 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500345 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000346 {
347 bindIndexedUniformBuffer(0, i, 0, -1);
348 }
349
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000350 bindCopyReadBuffer(0);
351 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000352 bindPixelPackBuffer(0);
353 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000354
Geoff Langeb66a6e2016-10-31 13:06:12 -0400355 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400356 {
357 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
358 // In the initial state, a default transform feedback object is bound and treated as
359 // a transform feedback object with a name of zero. That object is bound any time
360 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400361 bindTransformFeedback(0);
362 }
Geoff Langc8058452014-02-03 12:04:11 -0500363
Jamie Madillad9f24e2016-02-12 09:27:24 -0500364 // Initialize dirty bit masks
365 // TODO(jmadill): additional ES3 state
366 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
367 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
368 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
369 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
370 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500373 // No dirty objects.
374
375 // Readpixels uses the pack state and read FBO
376 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
377 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
378 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
379 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
380 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500382 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
383
384 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
385 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
386 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
387 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
388 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
389 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
390 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
391 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
392 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
393 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
394 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
395 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
396
397 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
398 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700399 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500400 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
401 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400402
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400403 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000404}
405
Jamie Madill4928b7c2017-06-20 12:57:39 -0400406egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407{
Corentin Wallez80b24112015-08-25 16:41:57 -0400408 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000409 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000411 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400412 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000413
Corentin Wallez80b24112015-08-25 16:41:57 -0400414 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000415 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400416 if (query.second != nullptr)
417 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400418 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400419 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400421 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422
Corentin Wallez80b24112015-08-25 16:41:57 -0400423 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400424 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400425 if (vertexArray.second)
426 {
427 vertexArray.second->onDestroy(this);
428 }
Jamie Madill57a89722013-07-02 11:57:03 -0400429 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400430 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400431
Corentin Wallez80b24112015-08-25 16:41:57 -0400432 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500433 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500434 if (transformFeedback.second != nullptr)
435 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500436 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500437 }
Geoff Langc8058452014-02-03 12:04:11 -0500438 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400439 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500440
Jamie Madilldedd7b92014-11-05 16:30:36 -0500441 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400442 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400443 zeroTexture.second->onDestroy(this);
444 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400445 }
446 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000447
Corentin Wallezccab69d2017-01-27 16:57:15 -0500448 SafeDelete(mSurfacelessFramebuffer);
449
Jamie Madill4928b7c2017-06-20 12:57:39 -0400450 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400451 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500452
Jamie Madill4928b7c2017-06-20 12:57:39 -0400453 mGLState.reset(this);
454
Jamie Madill6c1f6712017-02-14 19:08:04 -0500455 mState.mBuffers->release(this);
456 mState.mShaderPrograms->release(this);
457 mState.mTextures->release(this);
458 mState.mRenderbuffers->release(this);
459 mState.mSamplers->release(this);
460 mState.mFenceSyncs->release(this);
461 mState.mPaths->release(this);
462 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400463
464 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000465}
466
Jamie Madill70ee0f62017-02-06 16:04:20 -0500467Context::~Context()
468{
469}
470
Jamie Madill4928b7c2017-06-20 12:57:39 -0400471egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000472{
Jamie Madill61e16b42017-06-19 11:13:23 -0400473 mCurrentDisplay = display;
474
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000475 if (!mHasBeenCurrent)
476 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000477 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500478 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400479 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000480
Corentin Wallezc295e512017-01-27 17:47:50 -0500481 int width = 0;
482 int height = 0;
483 if (surface != nullptr)
484 {
485 width = surface->getWidth();
486 height = surface->getHeight();
487 }
488
489 mGLState.setViewportParams(0, 0, width, height);
490 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000491
492 mHasBeenCurrent = true;
493 }
494
Jamie Madill1b94d432015-08-07 13:23:23 -0400495 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700496 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400497
Jamie Madill4928b7c2017-06-20 12:57:39 -0400498 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500499
500 Framebuffer *newDefault = nullptr;
501 if (surface != nullptr)
502 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400503 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500504 mCurrentSurface = surface;
505 newDefault = surface->getDefaultFramebuffer();
506 }
507 else
508 {
509 if (mSurfacelessFramebuffer == nullptr)
510 {
511 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
512 }
513
514 newDefault = mSurfacelessFramebuffer;
515 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000516
Corentin Wallez37c39792015-08-20 14:19:46 -0400517 // Update default framebuffer, the binding of the previous default
518 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400519 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700520 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400521 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700522 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400523 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700524 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400525 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700526 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400527 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500528 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400529 }
Ian Ewell292f0052016-02-04 10:37:32 -0500530
531 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400532 mImplementation->onMakeCurrent(this);
533 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000534}
535
Jamie Madill4928b7c2017-06-20 12:57:39 -0400536egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400537{
Corentin Wallez37c39792015-08-20 14:19:46 -0400538 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500539 Framebuffer *currentDefault = nullptr;
540 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400541 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500542 currentDefault = mCurrentSurface->getDefaultFramebuffer();
543 }
544 else if (mSurfacelessFramebuffer != nullptr)
545 {
546 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400547 }
548
Corentin Wallezc295e512017-01-27 17:47:50 -0500549 if (mGLState.getReadFramebuffer() == currentDefault)
550 {
551 mGLState.setReadFramebufferBinding(nullptr);
552 }
553 if (mGLState.getDrawFramebuffer() == currentDefault)
554 {
555 mGLState.setDrawFramebufferBinding(nullptr);
556 }
557 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
558
559 if (mCurrentSurface)
560 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400561 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500562 mCurrentSurface = nullptr;
563 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400564
565 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400566}
567
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000568GLuint Context::createBuffer()
569{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500570 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000571}
572
573GLuint Context::createProgram()
574{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500575 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000576}
577
578GLuint Context::createShader(GLenum type)
579{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500580 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000581}
582
583GLuint Context::createTexture()
584{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500585 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000586}
587
588GLuint Context::createRenderbuffer()
589{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500590 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000591}
592
Geoff Lang882033e2014-09-30 11:26:07 -0400593GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400594{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500595 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400596
Cooper Partind8e62a32015-01-29 15:21:25 -0800597 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400598}
599
Sami Väisänene45e53b2016-05-25 10:36:04 +0300600GLuint Context::createPaths(GLsizei range)
601{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500602 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300603 if (resultOrError.isError())
604 {
605 handleError(resultOrError.getError());
606 return 0;
607 }
608 return resultOrError.getResult();
609}
610
Jamie Madill57a89722013-07-02 11:57:03 -0400611GLuint Context::createVertexArray()
612{
Jamie Madill96a483b2017-06-27 16:49:21 -0400613 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
614 mVertexArrayMap.assign(vertexArray, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500615 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400616}
617
Jamie Madilldc356042013-07-19 16:36:57 -0400618GLuint Context::createSampler()
619{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500620 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400621}
622
Geoff Langc8058452014-02-03 12:04:11 -0500623GLuint Context::createTransformFeedback()
624{
Jamie Madill96a483b2017-06-27 16:49:21 -0400625 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
626 mTransformFeedbackMap.assign(transformFeedback, nullptr);
Geoff Lang36167ab2015-12-07 10:27:14 -0500627 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500628}
629
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630// Returns an unused framebuffer name
631GLuint Context::createFramebuffer()
632{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500633 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000634}
635
Jamie Madill33dc8432013-07-26 11:55:05 -0400636GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637{
Jamie Madill33dc8432013-07-26 11:55:05 -0400638 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400639 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000640 return handle;
641}
642
643// Returns an unused query name
644GLuint Context::createQuery()
645{
646 GLuint handle = mQueryHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400647 mQueryMap.assign(handle, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000648 return handle;
649}
650
651void Context::deleteBuffer(GLuint buffer)
652{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500653 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000654 {
655 detachBuffer(buffer);
656 }
Jamie Madill893ab082014-05-16 16:56:10 -0400657
Jamie Madill6c1f6712017-02-14 19:08:04 -0500658 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659}
660
661void Context::deleteShader(GLuint shader)
662{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500663 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000664}
665
666void Context::deleteProgram(GLuint program)
667{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500668 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000669}
670
671void Context::deleteTexture(GLuint texture)
672{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500673 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000674 {
675 detachTexture(texture);
676 }
677
Jamie Madill6c1f6712017-02-14 19:08:04 -0500678 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000679}
680
681void Context::deleteRenderbuffer(GLuint renderbuffer)
682{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500683 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000684 {
685 detachRenderbuffer(renderbuffer);
686 }
Jamie Madill893ab082014-05-16 16:56:10 -0400687
Jamie Madill6c1f6712017-02-14 19:08:04 -0500688 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000689}
690
Jamie Madillcd055f82013-07-26 11:55:15 -0400691void Context::deleteFenceSync(GLsync fenceSync)
692{
693 // The spec specifies the underlying Fence object is not deleted until all current
694 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
695 // and since our API is currently designed for being called from a single thread, we can delete
696 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500697 mState.mFenceSyncs->deleteObject(this,
698 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400699}
700
Sami Väisänene45e53b2016-05-25 10:36:04 +0300701void Context::deletePaths(GLuint first, GLsizei range)
702{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500703 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300704}
705
706bool Context::hasPathData(GLuint path) const
707{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500708 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300709 if (pathObj == nullptr)
710 return false;
711
712 return pathObj->hasPathData();
713}
714
715bool Context::hasPath(GLuint path) const
716{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500717 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300718}
719
720void Context::setPathCommands(GLuint path,
721 GLsizei numCommands,
722 const GLubyte *commands,
723 GLsizei numCoords,
724 GLenum coordType,
725 const void *coords)
726{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500727 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300728
729 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
730}
731
732void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
733{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500734 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300735
736 switch (pname)
737 {
738 case GL_PATH_STROKE_WIDTH_CHROMIUM:
739 pathObj->setStrokeWidth(value);
740 break;
741 case GL_PATH_END_CAPS_CHROMIUM:
742 pathObj->setEndCaps(static_cast<GLenum>(value));
743 break;
744 case GL_PATH_JOIN_STYLE_CHROMIUM:
745 pathObj->setJoinStyle(static_cast<GLenum>(value));
746 break;
747 case GL_PATH_MITER_LIMIT_CHROMIUM:
748 pathObj->setMiterLimit(value);
749 break;
750 case GL_PATH_STROKE_BOUND_CHROMIUM:
751 pathObj->setStrokeBound(value);
752 break;
753 default:
754 UNREACHABLE();
755 break;
756 }
757}
758
759void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
760{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500761 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300762
763 switch (pname)
764 {
765 case GL_PATH_STROKE_WIDTH_CHROMIUM:
766 *value = pathObj->getStrokeWidth();
767 break;
768 case GL_PATH_END_CAPS_CHROMIUM:
769 *value = static_cast<GLfloat>(pathObj->getEndCaps());
770 break;
771 case GL_PATH_JOIN_STYLE_CHROMIUM:
772 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
773 break;
774 case GL_PATH_MITER_LIMIT_CHROMIUM:
775 *value = pathObj->getMiterLimit();
776 break;
777 case GL_PATH_STROKE_BOUND_CHROMIUM:
778 *value = pathObj->getStrokeBound();
779 break;
780 default:
781 UNREACHABLE();
782 break;
783 }
784}
785
786void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
787{
788 mGLState.setPathStencilFunc(func, ref, mask);
789}
790
Jamie Madill57a89722013-07-02 11:57:03 -0400791void Context::deleteVertexArray(GLuint vertexArray)
792{
Jamie Madill96a483b2017-06-27 16:49:21 -0400793 VertexArray *vertexArrayObject = nullptr;
794 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
Geoff Lang50b3fe82015-12-08 14:49:12 +0000795 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500796 if (vertexArrayObject != nullptr)
797 {
798 detachVertexArray(vertexArray);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400799 vertexArrayObject->onDestroy(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500800 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000801
Geoff Lang36167ab2015-12-07 10:27:14 -0500802 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400803 }
804}
805
Jamie Madilldc356042013-07-19 16:36:57 -0400806void Context::deleteSampler(GLuint sampler)
807{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500808 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400809 {
810 detachSampler(sampler);
811 }
812
Jamie Madill6c1f6712017-02-14 19:08:04 -0500813 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400814}
815
Geoff Langc8058452014-02-03 12:04:11 -0500816void Context::deleteTransformFeedback(GLuint transformFeedback)
817{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400818 if (transformFeedback == 0)
819 {
820 return;
821 }
822
Jamie Madill96a483b2017-06-27 16:49:21 -0400823 TransformFeedback *transformFeedbackObject = nullptr;
824 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
Geoff Langc8058452014-02-03 12:04:11 -0500825 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500826 if (transformFeedbackObject != nullptr)
827 {
828 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500829 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500830 }
831
Geoff Lang36167ab2015-12-07 10:27:14 -0500832 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500833 }
834}
835
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000836void Context::deleteFramebuffer(GLuint framebuffer)
837{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500838 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000839 {
840 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000841 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500842
Jamie Madill6c1f6712017-02-14 19:08:04 -0500843 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000844}
845
Jamie Madill33dc8432013-07-26 11:55:05 -0400846void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847{
Jamie Madill96a483b2017-06-27 16:49:21 -0400848 FenceNV *fenceObject = nullptr;
849 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400851 mFenceNVHandleAllocator.release(fence);
852 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000853 }
854}
855
856void Context::deleteQuery(GLuint query)
857{
Jamie Madill96a483b2017-06-27 16:49:21 -0400858 Query *queryObject = nullptr;
859 if (mQueryMap.erase(query, &queryObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000860 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400861 mQueryHandleAllocator.release(query);
862 if (queryObject)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000863 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400864 queryObject->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000865 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000866 }
867}
868
Geoff Lang70d0f492015-12-10 17:45:46 -0500869Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000870{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500871 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000872}
873
Jamie Madill570f7c82014-07-03 10:38:54 -0400874Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000875{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500876 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000877}
878
Geoff Lang70d0f492015-12-10 17:45:46 -0500879Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000880{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500881 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000882}
883
Jamie Madillcd055f82013-07-26 11:55:15 -0400884FenceSync *Context::getFenceSync(GLsync handle) const
885{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500886 return mState.mFenceSyncs->getFenceSync(
887 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400888}
889
Jamie Madill57a89722013-07-02 11:57:03 -0400890VertexArray *Context::getVertexArray(GLuint handle) const
891{
Jamie Madill96a483b2017-06-27 16:49:21 -0400892 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400893}
894
Jamie Madilldc356042013-07-19 16:36:57 -0400895Sampler *Context::getSampler(GLuint handle) const
896{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500897 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400898}
899
Geoff Langc8058452014-02-03 12:04:11 -0500900TransformFeedback *Context::getTransformFeedback(GLuint handle) const
901{
Jamie Madill96a483b2017-06-27 16:49:21 -0400902 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500903}
904
Geoff Lang70d0f492015-12-10 17:45:46 -0500905LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
906{
907 switch (identifier)
908 {
909 case GL_BUFFER:
910 return getBuffer(name);
911 case GL_SHADER:
912 return getShader(name);
913 case GL_PROGRAM:
914 return getProgram(name);
915 case GL_VERTEX_ARRAY:
916 return getVertexArray(name);
917 case GL_QUERY:
918 return getQuery(name);
919 case GL_TRANSFORM_FEEDBACK:
920 return getTransformFeedback(name);
921 case GL_SAMPLER:
922 return getSampler(name);
923 case GL_TEXTURE:
924 return getTexture(name);
925 case GL_RENDERBUFFER:
926 return getRenderbuffer(name);
927 case GL_FRAMEBUFFER:
928 return getFramebuffer(name);
929 default:
930 UNREACHABLE();
931 return nullptr;
932 }
933}
934
935LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
936{
937 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
938}
939
Martin Radev9d901792016-07-15 15:58:58 +0300940void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
941{
942 LabeledObject *object = getLabeledObject(identifier, name);
943 ASSERT(object != nullptr);
944
945 std::string labelName = GetObjectLabelFromPointer(length, label);
946 object->setLabel(labelName);
947}
948
949void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
950{
951 LabeledObject *object = getLabeledObjectFromPtr(ptr);
952 ASSERT(object != nullptr);
953
954 std::string labelName = GetObjectLabelFromPointer(length, label);
955 object->setLabel(labelName);
956}
957
958void Context::getObjectLabel(GLenum identifier,
959 GLuint name,
960 GLsizei bufSize,
961 GLsizei *length,
962 GLchar *label) const
963{
964 LabeledObject *object = getLabeledObject(identifier, name);
965 ASSERT(object != nullptr);
966
967 const std::string &objectLabel = object->getLabel();
968 GetObjectLabelBase(objectLabel, bufSize, length, label);
969}
970
971void Context::getObjectPtrLabel(const void *ptr,
972 GLsizei bufSize,
973 GLsizei *length,
974 GLchar *label) const
975{
976 LabeledObject *object = getLabeledObjectFromPtr(ptr);
977 ASSERT(object != nullptr);
978
979 const std::string &objectLabel = object->getLabel();
980 GetObjectLabelBase(objectLabel, bufSize, length, label);
981}
982
Jamie Madilldc356042013-07-19 16:36:57 -0400983bool Context::isSampler(GLuint samplerName) const
984{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500985 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400986}
987
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500988void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500990 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400991 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992}
993
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800994void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
995{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500996 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400997 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800998}
999
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001000void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001001{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001002 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001003 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004}
1005
Jamie Madilldedd7b92014-11-05 16:30:36 -05001006void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001007{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001008 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001009
Jamie Madilldedd7b92014-11-05 16:30:36 -05001010 if (handle == 0)
1011 {
1012 texture = mZeroTextures[target].get();
1013 }
1014 else
1015 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001016 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001017 }
1018
1019 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001020 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001021}
1022
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001023void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001024{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001025 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1026 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001028}
1029
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001030void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001031{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001032 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1033 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001034 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001038{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001040 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001041}
1042
Shao80957d92017-02-20 21:25:59 +08001043void Context::bindVertexBuffer(GLuint bindingIndex,
1044 GLuint bufferHandle,
1045 GLintptr offset,
1046 GLsizei stride)
1047{
1048 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001049 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001050}
1051
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001052void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001053{
Geoff Lang76b10c92014-09-05 16:28:14 -04001054 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001055 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001056 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001057 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001058}
1059
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001060void Context::bindImageTexture(GLuint unit,
1061 GLuint texture,
1062 GLint level,
1063 GLboolean layered,
1064 GLint layer,
1065 GLenum access,
1066 GLenum format)
1067{
1068 Texture *tex = mState.mTextures->getTexture(texture);
1069 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1070}
1071
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001072void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001073{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001074 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001075 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001076}
1077
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001078void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1079 GLuint index,
1080 GLintptr offset,
1081 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001082{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001083 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001084 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001085}
1086
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001087void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001088{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001089 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001090 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001091}
1092
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001093void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1094 GLuint index,
1095 GLintptr offset,
1096 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001097{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001098 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001099 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001100}
1101
Jiajia Qin6eafb042016-12-27 17:04:07 +08001102void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1103{
1104 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001105 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001106}
1107
1108void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1109 GLuint index,
1110 GLintptr offset,
1111 GLsizeiptr size)
1112{
1113 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001114 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001115}
1116
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001117void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1118{
1119 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001120 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001121}
1122
1123void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1124 GLuint index,
1125 GLintptr offset,
1126 GLsizeiptr size)
1127{
1128 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001129 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001130}
1131
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001132void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001133{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001134 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001135 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001136}
1137
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001138void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001139{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001140 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001141 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001142}
1143
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001144void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001145{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001146 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001147 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001148}
1149
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001150void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001151{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001152 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001153 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001154}
1155
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001156void Context::useProgram(GLuint program)
1157{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001158 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001159}
1160
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001161void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001162{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001163 TransformFeedback *transformFeedback =
1164 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001165 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001166}
1167
Geoff Lang5aad9672014-09-08 11:10:42 -04001168Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001169{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001170 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001171 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172
Geoff Lang5aad9672014-09-08 11:10:42 -04001173 // begin query
1174 Error error = queryObject->begin();
1175 if (error.isError())
1176 {
1177 return error;
1178 }
1179
1180 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001181 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001182
He Yunchaoacd18982017-01-04 10:46:42 +08001183 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184}
1185
Geoff Lang5aad9672014-09-08 11:10:42 -04001186Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001188 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001189 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001190
Geoff Lang5aad9672014-09-08 11:10:42 -04001191 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001192
Geoff Lang5aad9672014-09-08 11:10:42 -04001193 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001194 mGLState.setActiveQuery(this, target, nullptr);
Geoff Lang5aad9672014-09-08 11:10:42 -04001195
1196 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197}
1198
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001199Error Context::queryCounter(GLuint id, GLenum target)
1200{
1201 ASSERT(target == GL_TIMESTAMP_EXT);
1202
1203 Query *queryObject = getQuery(id, true, target);
1204 ASSERT(queryObject);
1205
1206 return queryObject->queryCounter();
1207}
1208
1209void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1210{
1211 switch (pname)
1212 {
1213 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001214 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001215 break;
1216 case GL_QUERY_COUNTER_BITS_EXT:
1217 switch (target)
1218 {
1219 case GL_TIME_ELAPSED_EXT:
1220 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1221 break;
1222 case GL_TIMESTAMP_EXT:
1223 params[0] = getExtensions().queryCounterBitsTimestamp;
1224 break;
1225 default:
1226 UNREACHABLE();
1227 params[0] = 0;
1228 break;
1229 }
1230 break;
1231 default:
1232 UNREACHABLE();
1233 return;
1234 }
1235}
1236
Geoff Lang2186c382016-10-14 10:54:54 -04001237void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001238{
Geoff Lang2186c382016-10-14 10:54:54 -04001239 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001240}
1241
Geoff Lang2186c382016-10-14 10:54:54 -04001242void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001243{
Geoff Lang2186c382016-10-14 10:54:54 -04001244 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001245}
1246
Geoff Lang2186c382016-10-14 10:54:54 -04001247void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001248{
Geoff Lang2186c382016-10-14 10:54:54 -04001249 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001250}
1251
Geoff Lang2186c382016-10-14 10:54:54 -04001252void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001253{
Geoff Lang2186c382016-10-14 10:54:54 -04001254 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001255}
1256
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001257Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001258{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001259 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001260}
1261
Jamie Madill2f348d22017-06-05 10:50:59 -04001262FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263{
Jamie Madill96a483b2017-06-27 16:49:21 -04001264 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001265}
1266
Jamie Madill2f348d22017-06-05 10:50:59 -04001267Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268{
Jamie Madill96a483b2017-06-27 16:49:21 -04001269 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001271 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001273
1274 Query *query = mQueryMap.query(handle);
1275 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001277 query = new Query(mImplementation->createQuery(type), handle);
1278 query->addRef();
1279 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001281 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001282}
1283
Geoff Lang70d0f492015-12-10 17:45:46 -05001284Query *Context::getQuery(GLuint handle) const
1285{
Jamie Madill96a483b2017-06-27 16:49:21 -04001286 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001287}
1288
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001289Texture *Context::getTargetTexture(GLenum target) const
1290{
Ian Ewellbda75592016-04-18 17:25:54 -04001291 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001292 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001293}
1294
Geoff Lang76b10c92014-09-05 16:28:14 -04001295Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001296{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001297 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001298}
1299
Geoff Lang492a7e42014-11-05 13:27:06 -05001300Compiler *Context::getCompiler() const
1301{
Jamie Madill2f348d22017-06-05 10:50:59 -04001302 if (mCompiler.get() == nullptr)
1303 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001304 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001305 }
1306 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001307}
1308
Jamie Madillc1d770e2017-04-13 17:31:24 -04001309void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001310{
1311 switch (pname)
1312 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001313 case GL_SHADER_COMPILER:
1314 *params = GL_TRUE;
1315 break;
1316 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1317 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1318 break;
1319 default:
1320 mGLState.getBooleanv(pname, params);
1321 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001323}
1324
Jamie Madillc1d770e2017-04-13 17:31:24 -04001325void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326{
Shannon Woods53a94a82014-06-24 15:20:36 -04001327 // Queries about context capabilities and maximums are answered by Context.
1328 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001329 switch (pname)
1330 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001331 case GL_ALIASED_LINE_WIDTH_RANGE:
1332 params[0] = mCaps.minAliasedLineWidth;
1333 params[1] = mCaps.maxAliasedLineWidth;
1334 break;
1335 case GL_ALIASED_POINT_SIZE_RANGE:
1336 params[0] = mCaps.minAliasedPointSize;
1337 params[1] = mCaps.maxAliasedPointSize;
1338 break;
1339 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1340 ASSERT(mExtensions.textureFilterAnisotropic);
1341 *params = mExtensions.maxTextureAnisotropy;
1342 break;
1343 case GL_MAX_TEXTURE_LOD_BIAS:
1344 *params = mCaps.maxLODBias;
1345 break;
1346
1347 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1348 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1349 {
1350 ASSERT(mExtensions.pathRendering);
1351 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1352 memcpy(params, m, 16 * sizeof(GLfloat));
1353 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001354 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001355
Jamie Madill231c7f52017-04-26 13:45:37 -04001356 default:
1357 mGLState.getFloatv(pname, params);
1358 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001359 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001360}
1361
Jamie Madillc1d770e2017-04-13 17:31:24 -04001362void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001363{
Shannon Woods53a94a82014-06-24 15:20:36 -04001364 // Queries about context capabilities and maximums are answered by Context.
1365 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001366
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001367 switch (pname)
1368 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001369 case GL_MAX_VERTEX_ATTRIBS:
1370 *params = mCaps.maxVertexAttributes;
1371 break;
1372 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1373 *params = mCaps.maxVertexUniformVectors;
1374 break;
1375 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1376 *params = mCaps.maxVertexUniformComponents;
1377 break;
1378 case GL_MAX_VARYING_VECTORS:
1379 *params = mCaps.maxVaryingVectors;
1380 break;
1381 case GL_MAX_VARYING_COMPONENTS:
1382 *params = mCaps.maxVertexOutputComponents;
1383 break;
1384 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1385 *params = mCaps.maxCombinedTextureImageUnits;
1386 break;
1387 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1388 *params = mCaps.maxVertexTextureImageUnits;
1389 break;
1390 case GL_MAX_TEXTURE_IMAGE_UNITS:
1391 *params = mCaps.maxTextureImageUnits;
1392 break;
1393 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1394 *params = mCaps.maxFragmentUniformVectors;
1395 break;
1396 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1397 *params = mCaps.maxFragmentUniformComponents;
1398 break;
1399 case GL_MAX_RENDERBUFFER_SIZE:
1400 *params = mCaps.maxRenderbufferSize;
1401 break;
1402 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1403 *params = mCaps.maxColorAttachments;
1404 break;
1405 case GL_MAX_DRAW_BUFFERS_EXT:
1406 *params = mCaps.maxDrawBuffers;
1407 break;
1408 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1409 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1410 case GL_SUBPIXEL_BITS:
1411 *params = 4;
1412 break;
1413 case GL_MAX_TEXTURE_SIZE:
1414 *params = mCaps.max2DTextureSize;
1415 break;
1416 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1417 *params = mCaps.maxCubeMapTextureSize;
1418 break;
1419 case GL_MAX_3D_TEXTURE_SIZE:
1420 *params = mCaps.max3DTextureSize;
1421 break;
1422 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1423 *params = mCaps.maxArrayTextureLayers;
1424 break;
1425 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1426 *params = mCaps.uniformBufferOffsetAlignment;
1427 break;
1428 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1429 *params = mCaps.maxUniformBufferBindings;
1430 break;
1431 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1432 *params = mCaps.maxVertexUniformBlocks;
1433 break;
1434 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1435 *params = mCaps.maxFragmentUniformBlocks;
1436 break;
1437 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1438 *params = mCaps.maxCombinedTextureImageUnits;
1439 break;
1440 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1441 *params = mCaps.maxVertexOutputComponents;
1442 break;
1443 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1444 *params = mCaps.maxFragmentInputComponents;
1445 break;
1446 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1447 *params = mCaps.minProgramTexelOffset;
1448 break;
1449 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1450 *params = mCaps.maxProgramTexelOffset;
1451 break;
1452 case GL_MAJOR_VERSION:
1453 *params = getClientVersion().major;
1454 break;
1455 case GL_MINOR_VERSION:
1456 *params = getClientVersion().minor;
1457 break;
1458 case GL_MAX_ELEMENTS_INDICES:
1459 *params = mCaps.maxElementsIndices;
1460 break;
1461 case GL_MAX_ELEMENTS_VERTICES:
1462 *params = mCaps.maxElementsVertices;
1463 break;
1464 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1465 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1466 break;
1467 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1468 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1469 break;
1470 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1471 *params = mCaps.maxTransformFeedbackSeparateComponents;
1472 break;
1473 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1474 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1475 break;
1476 case GL_MAX_SAMPLES_ANGLE:
1477 *params = mCaps.maxSamples;
1478 break;
1479 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001480 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001481 params[0] = mCaps.maxViewportWidth;
1482 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001483 }
1484 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001485 case GL_COMPRESSED_TEXTURE_FORMATS:
1486 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1487 params);
1488 break;
1489 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1490 *params = mResetStrategy;
1491 break;
1492 case GL_NUM_SHADER_BINARY_FORMATS:
1493 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1494 break;
1495 case GL_SHADER_BINARY_FORMATS:
1496 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1497 break;
1498 case GL_NUM_PROGRAM_BINARY_FORMATS:
1499 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1500 break;
1501 case GL_PROGRAM_BINARY_FORMATS:
1502 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1503 break;
1504 case GL_NUM_EXTENSIONS:
1505 *params = static_cast<GLint>(mExtensionStrings.size());
1506 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001507
Jamie Madill231c7f52017-04-26 13:45:37 -04001508 // GL_KHR_debug
1509 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1510 *params = mExtensions.maxDebugMessageLength;
1511 break;
1512 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1513 *params = mExtensions.maxDebugLoggedMessages;
1514 break;
1515 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1516 *params = mExtensions.maxDebugGroupStackDepth;
1517 break;
1518 case GL_MAX_LABEL_LENGTH:
1519 *params = mExtensions.maxLabelLength;
1520 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001521
Jamie Madill231c7f52017-04-26 13:45:37 -04001522 // GL_EXT_disjoint_timer_query
1523 case GL_GPU_DISJOINT_EXT:
1524 *params = mImplementation->getGPUDisjoint();
1525 break;
1526 case GL_MAX_FRAMEBUFFER_WIDTH:
1527 *params = mCaps.maxFramebufferWidth;
1528 break;
1529 case GL_MAX_FRAMEBUFFER_HEIGHT:
1530 *params = mCaps.maxFramebufferHeight;
1531 break;
1532 case GL_MAX_FRAMEBUFFER_SAMPLES:
1533 *params = mCaps.maxFramebufferSamples;
1534 break;
1535 case GL_MAX_SAMPLE_MASK_WORDS:
1536 *params = mCaps.maxSampleMaskWords;
1537 break;
1538 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1539 *params = mCaps.maxColorTextureSamples;
1540 break;
1541 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1542 *params = mCaps.maxDepthTextureSamples;
1543 break;
1544 case GL_MAX_INTEGER_SAMPLES:
1545 *params = mCaps.maxIntegerSamples;
1546 break;
1547 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1548 *params = mCaps.maxVertexAttribRelativeOffset;
1549 break;
1550 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1551 *params = mCaps.maxVertexAttribBindings;
1552 break;
1553 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1554 *params = mCaps.maxVertexAttribStride;
1555 break;
1556 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1557 *params = mCaps.maxVertexAtomicCounterBuffers;
1558 break;
1559 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1560 *params = mCaps.maxVertexAtomicCounters;
1561 break;
1562 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1563 *params = mCaps.maxVertexImageUniforms;
1564 break;
1565 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1566 *params = mCaps.maxVertexShaderStorageBlocks;
1567 break;
1568 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1569 *params = mCaps.maxFragmentAtomicCounterBuffers;
1570 break;
1571 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1572 *params = mCaps.maxFragmentAtomicCounters;
1573 break;
1574 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1575 *params = mCaps.maxFragmentImageUniforms;
1576 break;
1577 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1578 *params = mCaps.maxFragmentShaderStorageBlocks;
1579 break;
1580 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1581 *params = mCaps.minProgramTextureGatherOffset;
1582 break;
1583 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1584 *params = mCaps.maxProgramTextureGatherOffset;
1585 break;
1586 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1587 *params = mCaps.maxComputeWorkGroupInvocations;
1588 break;
1589 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1590 *params = mCaps.maxComputeUniformBlocks;
1591 break;
1592 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1593 *params = mCaps.maxComputeTextureImageUnits;
1594 break;
1595 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1596 *params = mCaps.maxComputeSharedMemorySize;
1597 break;
1598 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1599 *params = mCaps.maxComputeUniformComponents;
1600 break;
1601 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1602 *params = mCaps.maxComputeAtomicCounterBuffers;
1603 break;
1604 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1605 *params = mCaps.maxComputeAtomicCounters;
1606 break;
1607 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1608 *params = mCaps.maxComputeImageUniforms;
1609 break;
1610 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1611 *params = mCaps.maxCombinedComputeUniformComponents;
1612 break;
1613 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1614 *params = mCaps.maxComputeShaderStorageBlocks;
1615 break;
1616 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1617 *params = mCaps.maxCombinedShaderOutputResources;
1618 break;
1619 case GL_MAX_UNIFORM_LOCATIONS:
1620 *params = mCaps.maxUniformLocations;
1621 break;
1622 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1623 *params = mCaps.maxAtomicCounterBufferBindings;
1624 break;
1625 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1626 *params = mCaps.maxAtomicCounterBufferSize;
1627 break;
1628 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1629 *params = mCaps.maxCombinedAtomicCounterBuffers;
1630 break;
1631 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1632 *params = mCaps.maxCombinedAtomicCounters;
1633 break;
1634 case GL_MAX_IMAGE_UNITS:
1635 *params = mCaps.maxImageUnits;
1636 break;
1637 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1638 *params = mCaps.maxCombinedImageUniforms;
1639 break;
1640 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1641 *params = mCaps.maxShaderStorageBufferBindings;
1642 break;
1643 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1644 *params = mCaps.maxCombinedShaderStorageBlocks;
1645 break;
1646 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1647 *params = mCaps.shaderStorageBufferOffsetAlignment;
1648 break;
1649 default:
1650 mGLState.getIntegerv(this, pname, params);
1651 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001652 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001653}
1654
Jamie Madill893ab082014-05-16 16:56:10 -04001655void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001656{
Shannon Woods53a94a82014-06-24 15:20:36 -04001657 // Queries about context capabilities and maximums are answered by Context.
1658 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001659 switch (pname)
1660 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001661 case GL_MAX_ELEMENT_INDEX:
1662 *params = mCaps.maxElementIndex;
1663 break;
1664 case GL_MAX_UNIFORM_BLOCK_SIZE:
1665 *params = mCaps.maxUniformBlockSize;
1666 break;
1667 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1668 *params = mCaps.maxCombinedVertexUniformComponents;
1669 break;
1670 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1671 *params = mCaps.maxCombinedFragmentUniformComponents;
1672 break;
1673 case GL_MAX_SERVER_WAIT_TIMEOUT:
1674 *params = mCaps.maxServerWaitTimeout;
1675 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001676
Jamie Madill231c7f52017-04-26 13:45:37 -04001677 // GL_EXT_disjoint_timer_query
1678 case GL_TIMESTAMP_EXT:
1679 *params = mImplementation->getTimestamp();
1680 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001681
Jamie Madill231c7f52017-04-26 13:45:37 -04001682 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1683 *params = mCaps.maxShaderStorageBlockSize;
1684 break;
1685 default:
1686 UNREACHABLE();
1687 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001688 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001689}
1690
Geoff Lang70d0f492015-12-10 17:45:46 -05001691void Context::getPointerv(GLenum pname, void **params) const
1692{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001693 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001694}
1695
Martin Radev66fb8202016-07-28 11:45:20 +03001696void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001697{
Shannon Woods53a94a82014-06-24 15:20:36 -04001698 // Queries about context capabilities and maximums are answered by Context.
1699 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001700
1701 GLenum nativeType;
1702 unsigned int numParams;
1703 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1704 ASSERT(queryStatus);
1705
1706 if (nativeType == GL_INT)
1707 {
1708 switch (target)
1709 {
1710 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1711 ASSERT(index < 3u);
1712 *data = mCaps.maxComputeWorkGroupCount[index];
1713 break;
1714 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1715 ASSERT(index < 3u);
1716 *data = mCaps.maxComputeWorkGroupSize[index];
1717 break;
1718 default:
1719 mGLState.getIntegeri_v(target, index, data);
1720 }
1721 }
1722 else
1723 {
1724 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1725 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001726}
1727
Martin Radev66fb8202016-07-28 11:45:20 +03001728void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001729{
Shannon Woods53a94a82014-06-24 15:20:36 -04001730 // Queries about context capabilities and maximums are answered by Context.
1731 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001732
1733 GLenum nativeType;
1734 unsigned int numParams;
1735 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1736 ASSERT(queryStatus);
1737
1738 if (nativeType == GL_INT_64_ANGLEX)
1739 {
1740 mGLState.getInteger64i_v(target, index, data);
1741 }
1742 else
1743 {
1744 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1745 }
1746}
1747
1748void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1749{
1750 // Queries about context capabilities and maximums are answered by Context.
1751 // Queries about current GL state values are answered by State.
1752
1753 GLenum nativeType;
1754 unsigned int numParams;
1755 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1756 ASSERT(queryStatus);
1757
1758 if (nativeType == GL_BOOL)
1759 {
1760 mGLState.getBooleani_v(target, index, data);
1761 }
1762 else
1763 {
1764 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1765 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001766}
1767
He Yunchao010e4db2017-03-03 14:22:06 +08001768void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1769{
1770 Buffer *buffer = mGLState.getTargetBuffer(target);
1771 QueryBufferParameteriv(buffer, pname, params);
1772}
1773
1774void Context::getFramebufferAttachmentParameteriv(GLenum target,
1775 GLenum attachment,
1776 GLenum pname,
1777 GLint *params)
1778{
1779 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1780 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1781}
1782
1783void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1784{
1785 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1786 QueryRenderbufferiv(this, renderbuffer, pname, params);
1787}
1788
1789void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1790{
1791 Texture *texture = getTargetTexture(target);
1792 QueryTexParameterfv(texture, pname, params);
1793}
1794
1795void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1796{
1797 Texture *texture = getTargetTexture(target);
1798 QueryTexParameteriv(texture, pname, params);
1799}
1800void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1801{
1802 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001803 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001804}
1805
1806void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1807{
1808 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001809 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001810}
1811
1812void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1813{
1814 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001815 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001816}
1817
1818void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1819{
1820 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001821 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001822}
1823
Jamie Madill675fe712016-12-19 13:07:54 -05001824void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001825{
Jamie Madill1b94d432015-08-07 13:23:23 -04001826 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001827 auto error = mImplementation->drawArrays(this, mode, first, count);
Jamie Madill675fe712016-12-19 13:07:54 -05001828 handleError(error);
1829 if (!error.isError())
1830 {
1831 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1832 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001833}
1834
Jamie Madill675fe712016-12-19 13:07:54 -05001835void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001836{
1837 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001838 auto error = mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount);
Jamie Madill675fe712016-12-19 13:07:54 -05001839 handleError(error);
1840 if (!error.isError())
1841 {
1842 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1843 }
Geoff Langf6db0982015-08-25 13:04:00 -04001844}
1845
Jamie Madill876429b2017-04-20 15:46:24 -04001846void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001847{
Jamie Madill1b94d432015-08-07 13:23:23 -04001848 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001849 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001850 handleError(mImplementation->drawElements(this, mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001851}
1852
Jamie Madill675fe712016-12-19 13:07:54 -05001853void Context::drawElementsInstanced(GLenum mode,
1854 GLsizei count,
1855 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001856 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001857 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001858{
1859 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001860 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001861 handleError(mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances,
1862 indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001863}
1864
Jamie Madill675fe712016-12-19 13:07:54 -05001865void Context::drawRangeElements(GLenum mode,
1866 GLuint start,
1867 GLuint end,
1868 GLsizei count,
1869 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001870 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001871{
1872 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001873 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madillc564c072017-06-01 12:45:42 -04001874 handleError(mImplementation->drawRangeElements(this, mode, start, end, count, type, indices,
1875 indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001876}
1877
Jamie Madill876429b2017-04-20 15:46:24 -04001878void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001879{
1880 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001881 handleError(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001882}
1883
Jamie Madill876429b2017-04-20 15:46:24 -04001884void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001885{
1886 syncRendererState();
Jamie Madillc564c072017-06-01 12:45:42 -04001887 handleError(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001888}
1889
Jamie Madill675fe712016-12-19 13:07:54 -05001890void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001891{
Jamie Madill675fe712016-12-19 13:07:54 -05001892 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001893}
1894
Jamie Madill675fe712016-12-19 13:07:54 -05001895void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001896{
Jamie Madill675fe712016-12-19 13:07:54 -05001897 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001898}
1899
Austin Kinross6ee1e782015-05-29 17:05:37 -07001900void Context::insertEventMarker(GLsizei length, const char *marker)
1901{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001902 ASSERT(mImplementation);
1903 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001904}
1905
1906void Context::pushGroupMarker(GLsizei length, const char *marker)
1907{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001908 ASSERT(mImplementation);
1909 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001910}
1911
1912void Context::popGroupMarker()
1913{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001914 ASSERT(mImplementation);
1915 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001916}
1917
Geoff Langd8605522016-04-13 10:19:12 -04001918void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1919{
1920 Program *programObject = getProgram(program);
1921 ASSERT(programObject);
1922
1923 programObject->bindUniformLocation(location, name);
1924}
1925
Sami Väisänena797e062016-05-12 15:23:40 +03001926void Context::setCoverageModulation(GLenum components)
1927{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001928 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001929}
1930
Sami Väisänene45e53b2016-05-25 10:36:04 +03001931void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1932{
1933 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1934}
1935
1936void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1937{
1938 GLfloat I[16];
1939 angle::Matrix<GLfloat>::setToIdentity(I);
1940
1941 mGLState.loadPathRenderingMatrix(matrixMode, I);
1942}
1943
1944void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1945{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001946 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001947 if (!pathObj)
1948 return;
1949
1950 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1951 syncRendererState();
1952
1953 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1954}
1955
1956void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1957{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001958 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001959 if (!pathObj)
1960 return;
1961
1962 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1963 syncRendererState();
1964
1965 mImplementation->stencilStrokePath(pathObj, reference, mask);
1966}
1967
1968void Context::coverFillPath(GLuint path, GLenum coverMode)
1969{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001970 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001971 if (!pathObj)
1972 return;
1973
1974 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1975 syncRendererState();
1976
1977 mImplementation->coverFillPath(pathObj, coverMode);
1978}
1979
1980void Context::coverStrokePath(GLuint path, GLenum coverMode)
1981{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001982 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001983 if (!pathObj)
1984 return;
1985
1986 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1987 syncRendererState();
1988
1989 mImplementation->coverStrokePath(pathObj, coverMode);
1990}
1991
1992void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1993{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001994 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001995 if (!pathObj)
1996 return;
1997
1998 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1999 syncRendererState();
2000
2001 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
2002}
2003
2004void Context::stencilThenCoverStrokePath(GLuint path,
2005 GLint reference,
2006 GLuint mask,
2007 GLenum coverMode)
2008{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002009 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002010 if (!pathObj)
2011 return;
2012
2013 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2014 syncRendererState();
2015
2016 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2017}
2018
Sami Väisänend59ca052016-06-21 16:10:00 +03002019void Context::coverFillPathInstanced(GLsizei numPaths,
2020 GLenum pathNameType,
2021 const void *paths,
2022 GLuint pathBase,
2023 GLenum coverMode,
2024 GLenum transformType,
2025 const GLfloat *transformValues)
2026{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002027 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002028
2029 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2030 syncRendererState();
2031
2032 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2033}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002034
Sami Väisänend59ca052016-06-21 16:10:00 +03002035void Context::coverStrokePathInstanced(GLsizei numPaths,
2036 GLenum pathNameType,
2037 const void *paths,
2038 GLuint pathBase,
2039 GLenum coverMode,
2040 GLenum transformType,
2041 const GLfloat *transformValues)
2042{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002043 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002044
2045 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2046 syncRendererState();
2047
2048 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2049 transformValues);
2050}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002051
Sami Väisänend59ca052016-06-21 16:10:00 +03002052void Context::stencilFillPathInstanced(GLsizei numPaths,
2053 GLenum pathNameType,
2054 const void *paths,
2055 GLuint pathBase,
2056 GLenum fillMode,
2057 GLuint mask,
2058 GLenum transformType,
2059 const GLfloat *transformValues)
2060{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002061 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002062
2063 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2064 syncRendererState();
2065
2066 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2067 transformValues);
2068}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002069
Sami Väisänend59ca052016-06-21 16:10:00 +03002070void Context::stencilStrokePathInstanced(GLsizei numPaths,
2071 GLenum pathNameType,
2072 const void *paths,
2073 GLuint pathBase,
2074 GLint reference,
2075 GLuint mask,
2076 GLenum transformType,
2077 const GLfloat *transformValues)
2078{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002079 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002080
2081 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2082 syncRendererState();
2083
2084 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2085 transformValues);
2086}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002087
Sami Väisänend59ca052016-06-21 16:10:00 +03002088void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2089 GLenum pathNameType,
2090 const void *paths,
2091 GLuint pathBase,
2092 GLenum fillMode,
2093 GLuint mask,
2094 GLenum coverMode,
2095 GLenum transformType,
2096 const GLfloat *transformValues)
2097{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002098 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002099
2100 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2101 syncRendererState();
2102
2103 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2104 transformType, transformValues);
2105}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002106
Sami Väisänend59ca052016-06-21 16:10:00 +03002107void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2108 GLenum pathNameType,
2109 const void *paths,
2110 GLuint pathBase,
2111 GLint reference,
2112 GLuint mask,
2113 GLenum coverMode,
2114 GLenum transformType,
2115 const GLfloat *transformValues)
2116{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002117 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002118
2119 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2120 syncRendererState();
2121
2122 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2123 transformType, transformValues);
2124}
2125
Sami Väisänen46eaa942016-06-29 10:26:37 +03002126void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2127{
2128 auto *programObject = getProgram(program);
2129
2130 programObject->bindFragmentInputLocation(location, name);
2131}
2132
2133void Context::programPathFragmentInputGen(GLuint program,
2134 GLint location,
2135 GLenum genMode,
2136 GLint components,
2137 const GLfloat *coeffs)
2138{
2139 auto *programObject = getProgram(program);
2140
Jamie Madillbd044ed2017-06-05 12:59:21 -04002141 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002142}
2143
jchen1015015f72017-03-16 13:54:21 +08002144GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2145{
jchen10fd7c3b52017-03-21 15:36:03 +08002146 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002147 return QueryProgramResourceIndex(programObject, programInterface, name);
2148}
2149
jchen10fd7c3b52017-03-21 15:36:03 +08002150void Context::getProgramResourceName(GLuint program,
2151 GLenum programInterface,
2152 GLuint index,
2153 GLsizei bufSize,
2154 GLsizei *length,
2155 GLchar *name)
2156{
2157 const auto *programObject = getProgram(program);
2158 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2159}
2160
Jamie Madill437fa652016-05-03 15:13:24 -04002161void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002162{
Geoff Langda5777c2014-07-11 09:52:58 -04002163 if (error.isError())
2164 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002165 GLenum code = error.getCode();
2166 mErrors.insert(code);
2167 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2168 {
2169 markContextLost();
2170 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002171
2172 if (!error.getMessage().empty())
2173 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002174 auto *debug = &mGLState.getDebug();
2175 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2176 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002177 }
Geoff Langda5777c2014-07-11 09:52:58 -04002178 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002179}
2180
2181// Get one of the recorded errors and clear its flag, if any.
2182// [OpenGL ES 2.0.24] section 2.5 page 13.
2183GLenum Context::getError()
2184{
Geoff Langda5777c2014-07-11 09:52:58 -04002185 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002186 {
Geoff Langda5777c2014-07-11 09:52:58 -04002187 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002188 }
Geoff Langda5777c2014-07-11 09:52:58 -04002189 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002190 {
Geoff Langda5777c2014-07-11 09:52:58 -04002191 GLenum error = *mErrors.begin();
2192 mErrors.erase(mErrors.begin());
2193 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002194 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002195}
2196
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002197// NOTE: this function should not assume that this context is current!
2198void Context::markContextLost()
2199{
2200 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002201 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002202 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002203 mContextLostForced = true;
2204 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002205 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002206}
2207
2208bool Context::isContextLost()
2209{
2210 return mContextLost;
2211}
2212
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002213GLenum Context::getResetStatus()
2214{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002215 // Even if the application doesn't want to know about resets, we want to know
2216 // as it will allow us to skip all the calls.
2217 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002218 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002219 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002220 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002221 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002222 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002223
2224 // EXT_robustness, section 2.6: If the reset notification behavior is
2225 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2226 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2227 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002228 }
2229
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002230 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2231 // status should be returned at least once, and GL_NO_ERROR should be returned
2232 // once the device has finished resetting.
2233 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002234 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002235 ASSERT(mResetStatus == GL_NO_ERROR);
2236 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002237
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002238 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002239 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002240 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002241 }
2242 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002243 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002244 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002245 // If markContextLost was used to mark the context lost then
2246 // assume that is not recoverable, and continue to report the
2247 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002248 mResetStatus = mImplementation->getResetStatus();
2249 }
Jamie Madill893ab082014-05-16 16:56:10 -04002250
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002251 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002252}
2253
2254bool Context::isResetNotificationEnabled()
2255{
2256 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2257}
2258
Corentin Walleze3b10e82015-05-20 11:06:25 -04002259const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002260{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002261 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002262}
2263
2264EGLenum Context::getClientType() const
2265{
2266 return mClientType;
2267}
2268
2269EGLenum Context::getRenderBuffer() const
2270{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002271 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2272 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002273 {
2274 return EGL_NONE;
2275 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002276
2277 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2278 ASSERT(backAttachment != nullptr);
2279 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002280}
2281
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002282VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002283{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002284 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002285 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2286 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002287 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002288 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2289 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002290
Jamie Madill96a483b2017-06-27 16:49:21 -04002291 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002292 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002293
2294 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002295}
2296
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002297TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002298{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002299 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002300 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2301 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002302 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002303 transformFeedback =
2304 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002305 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002306 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002307 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002308
2309 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002310}
2311
2312bool Context::isVertexArrayGenerated(GLuint vertexArray)
2313{
Jamie Madill96a483b2017-06-27 16:49:21 -04002314 ASSERT(mVertexArrayMap.contains(0));
2315 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002316}
2317
2318bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2319{
Jamie Madill96a483b2017-06-27 16:49:21 -04002320 ASSERT(mTransformFeedbackMap.contains(0));
2321 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002322}
2323
Shannon Woods53a94a82014-06-24 15:20:36 -04002324void Context::detachTexture(GLuint texture)
2325{
2326 // Simple pass-through to State's detachTexture method, as textures do not require
2327 // allocation map management either here or in the resource manager at detach time.
2328 // Zero textures are held by the Context, and we don't attempt to request them from
2329 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002330 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002331}
2332
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002333void Context::detachBuffer(GLuint buffer)
2334{
Yuly Novikov5807a532015-12-03 13:01:22 -05002335 // Simple pass-through to State's detachBuffer method, since
2336 // only buffer attachments to container objects that are bound to the current context
2337 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002338
Yuly Novikov5807a532015-12-03 13:01:22 -05002339 // [OpenGL ES 3.2] section 5.1.2 page 45:
2340 // Attachments to unbound container objects, such as
2341 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2342 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002343 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002344}
2345
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002346void Context::detachFramebuffer(GLuint framebuffer)
2347{
Shannon Woods53a94a82014-06-24 15:20:36 -04002348 // Framebuffer detachment is handled by Context, because 0 is a valid
2349 // Framebuffer object, and a pointer to it must be passed from Context
2350 // to State at binding time.
2351
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002352 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002353 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2354 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2355 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002356
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002357 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002358 {
2359 bindReadFramebuffer(0);
2360 }
2361
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002362 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002363 {
2364 bindDrawFramebuffer(0);
2365 }
2366}
2367
2368void Context::detachRenderbuffer(GLuint renderbuffer)
2369{
Jamie Madilla02315b2017-02-23 14:14:47 -05002370 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002371}
2372
Jamie Madill57a89722013-07-02 11:57:03 -04002373void Context::detachVertexArray(GLuint vertexArray)
2374{
Jamie Madill77a72f62015-04-14 11:18:32 -04002375 // Vertex array detachment is handled by Context, because 0 is a valid
2376 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002377 // binding time.
2378
Jamie Madill57a89722013-07-02 11:57:03 -04002379 // [OpenGL ES 3.0.2] section 2.10 page 43:
2380 // If a vertex array object that is currently bound is deleted, the binding
2381 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002382 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002383 {
2384 bindVertexArray(0);
2385 }
2386}
2387
Geoff Langc8058452014-02-03 12:04:11 -05002388void Context::detachTransformFeedback(GLuint transformFeedback)
2389{
Corentin Walleza2257da2016-04-19 16:43:12 -04002390 // Transform feedback detachment is handled by Context, because 0 is a valid
2391 // transform feedback, and a pointer to it must be passed from Context to State at
2392 // binding time.
2393
2394 // The OpenGL specification doesn't mention what should happen when the currently bound
2395 // transform feedback object is deleted. Since it is a container object, we treat it like
2396 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002397 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002398 {
2399 bindTransformFeedback(0);
2400 }
Geoff Langc8058452014-02-03 12:04:11 -05002401}
2402
Jamie Madilldc356042013-07-19 16:36:57 -04002403void Context::detachSampler(GLuint sampler)
2404{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002405 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002406}
2407
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002408void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2409{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002410 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002411}
2412
Jamie Madille29d1672013-07-19 16:36:57 -04002413void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2414{
Geoff Langc1984ed2016-10-07 12:41:00 -04002415 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002416 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002417 SetSamplerParameteri(samplerObject, pname, param);
2418}
Jamie Madille29d1672013-07-19 16:36:57 -04002419
Geoff Langc1984ed2016-10-07 12:41:00 -04002420void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2421{
2422 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002423 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002424 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002425}
2426
2427void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2428{
Geoff Langc1984ed2016-10-07 12:41:00 -04002429 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002430 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002431 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002432}
2433
Geoff Langc1984ed2016-10-07 12:41:00 -04002434void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002435{
Geoff Langc1984ed2016-10-07 12:41:00 -04002436 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002437 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002438 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002439}
2440
Geoff Langc1984ed2016-10-07 12:41:00 -04002441void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002442{
Geoff Langc1984ed2016-10-07 12:41:00 -04002443 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002444 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002445 QuerySamplerParameteriv(samplerObject, pname, params);
2446}
Jamie Madill9675b802013-07-19 16:36:59 -04002447
Geoff Langc1984ed2016-10-07 12:41:00 -04002448void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2449{
2450 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002451 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002452 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002453}
2454
Olli Etuahof0fee072016-03-30 15:11:58 +03002455void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2456{
2457 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002458 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002459}
2460
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002461void Context::initRendererString()
2462{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002463 std::ostringstream rendererString;
2464 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002465 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002466 rendererString << ")";
2467
Geoff Langcec35902014-04-16 10:52:36 -04002468 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002469}
2470
Geoff Langc339c4e2016-11-29 10:37:36 -05002471void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002472{
Geoff Langc339c4e2016-11-29 10:37:36 -05002473 const Version &clientVersion = getClientVersion();
2474
2475 std::ostringstream versionString;
2476 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2477 << ANGLE_VERSION_STRING << ")";
2478 mVersionString = MakeStaticString(versionString.str());
2479
2480 std::ostringstream shadingLanguageVersionString;
2481 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2482 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2483 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2484 << ")";
2485 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002486}
2487
Geoff Langcec35902014-04-16 10:52:36 -04002488void Context::initExtensionStrings()
2489{
Geoff Langc339c4e2016-11-29 10:37:36 -05002490 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2491 std::ostringstream combinedStringStream;
2492 std::copy(strings.begin(), strings.end(),
2493 std::ostream_iterator<const char *>(combinedStringStream, " "));
2494 return MakeStaticString(combinedStringStream.str());
2495 };
2496
2497 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002498 for (const auto &extensionString : mExtensions.getStrings())
2499 {
2500 mExtensionStrings.push_back(MakeStaticString(extensionString));
2501 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002502 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002503
Bryan Bernhart58806562017-01-05 13:09:31 -08002504 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2505
Geoff Langc339c4e2016-11-29 10:37:36 -05002506 mRequestableExtensionStrings.clear();
2507 for (const auto &extensionInfo : GetExtensionInfoMap())
2508 {
2509 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002510 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2511 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002512 {
2513 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2514 }
2515 }
2516 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002517}
2518
Geoff Langc339c4e2016-11-29 10:37:36 -05002519const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002520{
Geoff Langc339c4e2016-11-29 10:37:36 -05002521 switch (name)
2522 {
2523 case GL_VENDOR:
2524 return reinterpret_cast<const GLubyte *>("Google Inc.");
2525
2526 case GL_RENDERER:
2527 return reinterpret_cast<const GLubyte *>(mRendererString);
2528
2529 case GL_VERSION:
2530 return reinterpret_cast<const GLubyte *>(mVersionString);
2531
2532 case GL_SHADING_LANGUAGE_VERSION:
2533 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2534
2535 case GL_EXTENSIONS:
2536 return reinterpret_cast<const GLubyte *>(mExtensionString);
2537
2538 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2539 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2540
2541 default:
2542 UNREACHABLE();
2543 return nullptr;
2544 }
Geoff Langcec35902014-04-16 10:52:36 -04002545}
2546
Geoff Langc339c4e2016-11-29 10:37:36 -05002547const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002548{
Geoff Langc339c4e2016-11-29 10:37:36 -05002549 switch (name)
2550 {
2551 case GL_EXTENSIONS:
2552 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2553
2554 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2555 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2556
2557 default:
2558 UNREACHABLE();
2559 return nullptr;
2560 }
Geoff Langcec35902014-04-16 10:52:36 -04002561}
2562
2563size_t Context::getExtensionStringCount() const
2564{
2565 return mExtensionStrings.size();
2566}
2567
Geoff Langc339c4e2016-11-29 10:37:36 -05002568void Context::requestExtension(const char *name)
2569{
2570 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2571 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2572 const auto &extension = extensionInfos.at(name);
2573 ASSERT(extension.Requestable);
2574
2575 if (mExtensions.*(extension.ExtensionsMember))
2576 {
2577 // Extension already enabled
2578 return;
2579 }
2580
2581 mExtensions.*(extension.ExtensionsMember) = true;
2582 updateCaps();
2583 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002584
Jamie Madill2f348d22017-06-05 10:50:59 -04002585 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2586 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002587
2588 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2589 // formats renderable or sampleable.
2590 mState.mTextures->invalidateTextureComplenessCache();
2591 for (auto &zeroTexture : mZeroTextures)
2592 {
2593 zeroTexture.second->invalidateCompletenessCache();
2594 }
2595
2596 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002597}
2598
2599size_t Context::getRequestableExtensionStringCount() const
2600{
2601 return mRequestableExtensionStrings.size();
2602}
2603
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002604void Context::beginTransformFeedback(GLenum primitiveMode)
2605{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002606 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002607 ASSERT(transformFeedback != nullptr);
2608 ASSERT(!transformFeedback->isPaused());
2609
Jamie Madill6c1f6712017-02-14 19:08:04 -05002610 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002611}
2612
2613bool Context::hasActiveTransformFeedback(GLuint program) const
2614{
2615 for (auto pair : mTransformFeedbackMap)
2616 {
2617 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2618 {
2619 return true;
2620 }
2621 }
2622 return false;
2623}
2624
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002625void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002626{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002627 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002628
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002629 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002630
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002631 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002632
Geoff Langeb66a6e2016-10-31 13:06:12 -04002633 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002634 {
2635 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002636 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002637 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002638 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002639 }
2640
Geoff Langeb66a6e2016-10-31 13:06:12 -04002641 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002642 {
2643 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002644 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002645 }
2646
Jamie Madill00ed7a12016-05-19 13:13:38 -04002647 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002648 mExtensions.bindUniformLocation = true;
2649 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002650 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002651 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002652 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002653
2654 // Enable the no error extension if the context was created with the flag.
2655 mExtensions.noError = mSkipValidation;
2656
Corentin Wallezccab69d2017-01-27 16:57:15 -05002657 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002658 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002659
Geoff Lang70d0f492015-12-10 17:45:46 -05002660 // Explicitly enable GL_KHR_debug
2661 mExtensions.debug = true;
2662 mExtensions.maxDebugMessageLength = 1024;
2663 mExtensions.maxDebugLoggedMessages = 1024;
2664 mExtensions.maxDebugGroupStackDepth = 1024;
2665 mExtensions.maxLabelLength = 1024;
2666
Geoff Langff5b2d52016-09-07 11:32:23 -04002667 // Explicitly enable GL_ANGLE_robust_client_memory
2668 mExtensions.robustClientMemory = true;
2669
Jamie Madille08a1d32017-03-07 17:24:06 -05002670 // Determine robust resource init availability from EGL.
2671 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002672 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002673
Geoff Lang301d1612014-07-09 10:34:37 -04002674 // Apply implementation limits
2675 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002676 mCaps.maxVertexAttribBindings =
2677 getClientVersion() < ES_3_1
2678 ? mCaps.maxVertexAttributes
2679 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2680
Jamie Madill231c7f52017-04-26 13:45:37 -04002681 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2682 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2683 mCaps.maxVertexOutputComponents =
2684 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002685
Jamie Madill231c7f52017-04-26 13:45:37 -04002686 mCaps.maxFragmentInputComponents =
2687 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002688
Geoff Langc287ea62016-09-16 14:46:51 -04002689 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002690 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002691 for (const auto &extensionInfo : GetExtensionInfoMap())
2692 {
2693 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002694 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002695 {
2696 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2697 }
2698 }
2699
2700 // Generate texture caps
2701 updateCaps();
2702}
2703
2704void Context::updateCaps()
2705{
Geoff Lang900013c2014-07-07 11:32:19 -04002706 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002707 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002708
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002709 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002710 {
Geoff Langca271392017-04-05 12:30:00 -04002711 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002712 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002713
Geoff Langca271392017-04-05 12:30:00 -04002714 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002715
Geoff Lang0d8b7242015-09-09 14:56:53 -04002716 // Update the format caps based on the client version and extensions.
2717 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2718 // ES3.
2719 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002720 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002721 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002722 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002723 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002724 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002725
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002726 // OpenGL ES does not support multisampling with non-rendererable formats
2727 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Yuly Novikovc8a8b842017-06-28 01:16:41 +00002728 if (!formatInfo.renderSupport ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002729 (getClientVersion() < ES_3_1 &&
2730 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002731 {
Geoff Langd87878e2014-09-19 15:42:59 -04002732 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002733 }
Geoff Langd87878e2014-09-19 15:42:59 -04002734
2735 if (formatCaps.texturable && formatInfo.compressed)
2736 {
Geoff Langca271392017-04-05 12:30:00 -04002737 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002738 }
2739
Geoff Langca271392017-04-05 12:30:00 -04002740 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002741 }
2742}
2743
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002744void Context::initWorkarounds()
2745{
Jamie Madill761b02c2017-06-23 16:27:06 -04002746 // Apply back-end workarounds.
2747 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2748
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002749 // Lose the context upon out of memory error if the application is
2750 // expecting to watch for those events.
2751 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2752}
2753
Jamie Madill1b94d432015-08-07 13:23:23 -04002754void Context::syncRendererState()
2755{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002756 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002757 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002758 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002759 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002760}
2761
Jamie Madillad9f24e2016-02-12 09:27:24 -05002762void Context::syncRendererState(const State::DirtyBits &bitMask,
2763 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002764{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002765 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002766 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002767 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002768 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002769}
Jamie Madillc29968b2016-01-20 11:17:23 -05002770
2771void Context::blitFramebuffer(GLint srcX0,
2772 GLint srcY0,
2773 GLint srcX1,
2774 GLint srcY1,
2775 GLint dstX0,
2776 GLint dstY0,
2777 GLint dstX1,
2778 GLint dstY1,
2779 GLbitfield mask,
2780 GLenum filter)
2781{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002782 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002783 ASSERT(drawFramebuffer);
2784
2785 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2786 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2787
Jamie Madillad9f24e2016-02-12 09:27:24 -05002788 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002789
Jamie Madillc564c072017-06-01 12:45:42 -04002790 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002791}
Jamie Madillc29968b2016-01-20 11:17:23 -05002792
2793void Context::clear(GLbitfield mask)
2794{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002795 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002796 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002797}
2798
2799void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2800{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002801 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002802 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002803}
2804
2805void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2806{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002807 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002808 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002809}
2810
2811void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2812{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002813 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002814 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002815}
2816
2817void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2818{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002820 ASSERT(framebufferObject);
2821
2822 // If a buffer is not present, the clear has no effect
2823 if (framebufferObject->getDepthbuffer() == nullptr &&
2824 framebufferObject->getStencilbuffer() == nullptr)
2825 {
2826 return;
2827 }
2828
Jamie Madillad9f24e2016-02-12 09:27:24 -05002829 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002830 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002831}
2832
2833void Context::readPixels(GLint x,
2834 GLint y,
2835 GLsizei width,
2836 GLsizei height,
2837 GLenum format,
2838 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002839 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002840{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002841 if (width == 0 || height == 0)
2842 {
2843 return;
2844 }
2845
Jamie Madillad9f24e2016-02-12 09:27:24 -05002846 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002847
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002848 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002849 ASSERT(framebufferObject);
2850
2851 Rectangle area(x, y, width, height);
Jamie Madillc564c072017-06-01 12:45:42 -04002852 handleError(framebufferObject->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002853}
2854
2855void Context::copyTexImage2D(GLenum target,
2856 GLint level,
2857 GLenum internalformat,
2858 GLint x,
2859 GLint y,
2860 GLsizei width,
2861 GLsizei height,
2862 GLint border)
2863{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002864 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002865 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002866
Jamie Madillc29968b2016-01-20 11:17:23 -05002867 Rectangle sourceArea(x, y, width, height);
2868
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002869 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002870 Texture *texture =
2871 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002872 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002873}
2874
2875void Context::copyTexSubImage2D(GLenum target,
2876 GLint level,
2877 GLint xoffset,
2878 GLint yoffset,
2879 GLint x,
2880 GLint y,
2881 GLsizei width,
2882 GLsizei height)
2883{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002884 if (width == 0 || height == 0)
2885 {
2886 return;
2887 }
2888
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002889 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002890 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002891
Jamie Madillc29968b2016-01-20 11:17:23 -05002892 Offset destOffset(xoffset, yoffset, 0);
2893 Rectangle sourceArea(x, y, width, height);
2894
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002895 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002896 Texture *texture =
2897 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002898 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002899}
2900
2901void Context::copyTexSubImage3D(GLenum target,
2902 GLint level,
2903 GLint xoffset,
2904 GLint yoffset,
2905 GLint zoffset,
2906 GLint x,
2907 GLint y,
2908 GLsizei width,
2909 GLsizei height)
2910{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002911 if (width == 0 || height == 0)
2912 {
2913 return;
2914 }
2915
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002916 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002917 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002918
Jamie Madillc29968b2016-01-20 11:17:23 -05002919 Offset destOffset(xoffset, yoffset, zoffset);
2920 Rectangle sourceArea(x, y, width, height);
2921
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002922 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002923 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002924 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002925}
2926
2927void Context::framebufferTexture2D(GLenum target,
2928 GLenum attachment,
2929 GLenum textarget,
2930 GLuint texture,
2931 GLint level)
2932{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002933 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002934 ASSERT(framebuffer);
2935
2936 if (texture != 0)
2937 {
2938 Texture *textureObj = getTexture(texture);
2939
2940 ImageIndex index = ImageIndex::MakeInvalid();
2941
2942 if (textarget == GL_TEXTURE_2D)
2943 {
2944 index = ImageIndex::Make2D(level);
2945 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002946 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2947 {
2948 ASSERT(level == 0);
2949 index = ImageIndex::Make2DMultisample();
2950 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002951 else
2952 {
2953 ASSERT(IsCubeMapTextureTarget(textarget));
2954 index = ImageIndex::MakeCube(textarget, level);
2955 }
2956
Jamie Madilla02315b2017-02-23 14:14:47 -05002957 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002958 }
2959 else
2960 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002961 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002962 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002963
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002964 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002965}
2966
2967void Context::framebufferRenderbuffer(GLenum target,
2968 GLenum attachment,
2969 GLenum renderbuffertarget,
2970 GLuint renderbuffer)
2971{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002972 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002973 ASSERT(framebuffer);
2974
2975 if (renderbuffer != 0)
2976 {
2977 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002978
2979 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002980 renderbufferObject);
2981 }
2982 else
2983 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002984 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002985 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002986
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002987 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002988}
2989
2990void Context::framebufferTextureLayer(GLenum target,
2991 GLenum attachment,
2992 GLuint texture,
2993 GLint level,
2994 GLint layer)
2995{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002996 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002997 ASSERT(framebuffer);
2998
2999 if (texture != 0)
3000 {
3001 Texture *textureObject = getTexture(texture);
3002
3003 ImageIndex index = ImageIndex::MakeInvalid();
3004
3005 if (textureObject->getTarget() == GL_TEXTURE_3D)
3006 {
3007 index = ImageIndex::Make3D(level, layer);
3008 }
3009 else
3010 {
3011 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3012 index = ImageIndex::Make2DArray(level, layer);
3013 }
3014
Jamie Madilla02315b2017-02-23 14:14:47 -05003015 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003016 }
3017 else
3018 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003019 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003020 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003021
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003022 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003023}
3024
3025void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3026{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003027 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003028 ASSERT(framebuffer);
3029 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003030 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003031}
3032
3033void Context::readBuffer(GLenum mode)
3034{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003035 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003036 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003037 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003038}
3039
3040void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3041{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003042 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003043 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003044
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003045 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003046 ASSERT(framebuffer);
3047
3048 // The specification isn't clear what should be done when the framebuffer isn't complete.
3049 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003050 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003051}
3052
3053void Context::invalidateFramebuffer(GLenum target,
3054 GLsizei numAttachments,
3055 const GLenum *attachments)
3056{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003057 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003058 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003059
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003060 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003061 ASSERT(framebuffer);
3062
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003063 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003064 {
Jamie Madill437fa652016-05-03 15:13:24 -04003065 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003066 }
Jamie Madill437fa652016-05-03 15:13:24 -04003067
Jamie Madill4928b7c2017-06-20 12:57:39 -04003068 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003069}
3070
3071void Context::invalidateSubFramebuffer(GLenum target,
3072 GLsizei numAttachments,
3073 const GLenum *attachments,
3074 GLint x,
3075 GLint y,
3076 GLsizei width,
3077 GLsizei height)
3078{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003079 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003080 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003081
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003082 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003083 ASSERT(framebuffer);
3084
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003085 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003086 {
Jamie Madill437fa652016-05-03 15:13:24 -04003087 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003088 }
Jamie Madill437fa652016-05-03 15:13:24 -04003089
3090 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003091 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003092}
3093
Jamie Madill73a84962016-02-12 09:27:23 -05003094void Context::texImage2D(GLenum target,
3095 GLint level,
3096 GLint internalformat,
3097 GLsizei width,
3098 GLsizei height,
3099 GLint border,
3100 GLenum format,
3101 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003102 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003103{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003104 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003105
3106 Extents size(width, height, 1);
3107 Texture *texture =
3108 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003109 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3110 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003111}
3112
3113void Context::texImage3D(GLenum target,
3114 GLint level,
3115 GLint internalformat,
3116 GLsizei width,
3117 GLsizei height,
3118 GLsizei depth,
3119 GLint border,
3120 GLenum format,
3121 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003122 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003123{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003124 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003125
3126 Extents size(width, height, depth);
3127 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003128 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3129 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003130}
3131
3132void Context::texSubImage2D(GLenum target,
3133 GLint level,
3134 GLint xoffset,
3135 GLint yoffset,
3136 GLsizei width,
3137 GLsizei height,
3138 GLenum format,
3139 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003140 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003141{
3142 // Zero sized uploads are valid but no-ops
3143 if (width == 0 || height == 0)
3144 {
3145 return;
3146 }
3147
Jamie Madillad9f24e2016-02-12 09:27:24 -05003148 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003149
3150 Box area(xoffset, yoffset, 0, width, height, 1);
3151 Texture *texture =
3152 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003153 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3154 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003155}
3156
3157void Context::texSubImage3D(GLenum target,
3158 GLint level,
3159 GLint xoffset,
3160 GLint yoffset,
3161 GLint zoffset,
3162 GLsizei width,
3163 GLsizei height,
3164 GLsizei depth,
3165 GLenum format,
3166 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003167 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003168{
3169 // Zero sized uploads are valid but no-ops
3170 if (width == 0 || height == 0 || depth == 0)
3171 {
3172 return;
3173 }
3174
Jamie Madillad9f24e2016-02-12 09:27:24 -05003175 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003176
3177 Box area(xoffset, yoffset, zoffset, width, height, depth);
3178 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003179 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3180 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003181}
3182
3183void Context::compressedTexImage2D(GLenum target,
3184 GLint level,
3185 GLenum internalformat,
3186 GLsizei width,
3187 GLsizei height,
3188 GLint border,
3189 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003190 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003191{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003192 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003193
3194 Extents size(width, height, 1);
3195 Texture *texture =
3196 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003197 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003198 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003199 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003200}
3201
3202void Context::compressedTexImage3D(GLenum target,
3203 GLint level,
3204 GLenum internalformat,
3205 GLsizei width,
3206 GLsizei height,
3207 GLsizei depth,
3208 GLint border,
3209 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003210 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003211{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003212 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003213
3214 Extents size(width, height, depth);
3215 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003216 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003217 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003218 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003219}
3220
3221void Context::compressedTexSubImage2D(GLenum target,
3222 GLint level,
3223 GLint xoffset,
3224 GLint yoffset,
3225 GLsizei width,
3226 GLsizei height,
3227 GLenum format,
3228 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003229 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003230{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003231 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003232
3233 Box area(xoffset, yoffset, 0, width, height, 1);
3234 Texture *texture =
3235 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003236 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003237 format, imageSize,
3238 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003239}
3240
3241void Context::compressedTexSubImage3D(GLenum target,
3242 GLint level,
3243 GLint xoffset,
3244 GLint yoffset,
3245 GLint zoffset,
3246 GLsizei width,
3247 GLsizei height,
3248 GLsizei depth,
3249 GLenum format,
3250 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003251 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003252{
3253 // Zero sized uploads are valid but no-ops
3254 if (width == 0 || height == 0)
3255 {
3256 return;
3257 }
3258
Jamie Madillad9f24e2016-02-12 09:27:24 -05003259 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003260
3261 Box area(xoffset, yoffset, zoffset, width, height, depth);
3262 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003263 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003264 format, imageSize,
3265 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003266}
3267
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003268void Context::generateMipmap(GLenum target)
3269{
3270 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003271 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003272}
3273
Geoff Lang97073d12016-04-20 10:42:34 -07003274void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003275 GLint sourceLevel,
3276 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003277 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003278 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003279 GLint internalFormat,
3280 GLenum destType,
3281 GLboolean unpackFlipY,
3282 GLboolean unpackPremultiplyAlpha,
3283 GLboolean unpackUnmultiplyAlpha)
3284{
3285 syncStateForTexImage();
3286
3287 gl::Texture *sourceTexture = getTexture(sourceId);
3288 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003289 handleError(destTexture->copyTexture(
3290 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3291 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003292}
3293
3294void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003295 GLint sourceLevel,
3296 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003297 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003298 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003299 GLint xoffset,
3300 GLint yoffset,
3301 GLint x,
3302 GLint y,
3303 GLsizei width,
3304 GLsizei height,
3305 GLboolean unpackFlipY,
3306 GLboolean unpackPremultiplyAlpha,
3307 GLboolean unpackUnmultiplyAlpha)
3308{
3309 // Zero sized copies are valid but no-ops
3310 if (width == 0 || height == 0)
3311 {
3312 return;
3313 }
3314
3315 syncStateForTexImage();
3316
3317 gl::Texture *sourceTexture = getTexture(sourceId);
3318 gl::Texture *destTexture = getTexture(destId);
3319 Offset offset(xoffset, yoffset, 0);
3320 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003321 handleError(destTexture->copySubTexture(
3322 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3323 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003324}
3325
Geoff Lang47110bf2016-04-20 11:13:22 -07003326void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3327{
3328 syncStateForTexImage();
3329
3330 gl::Texture *sourceTexture = getTexture(sourceId);
3331 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003332 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003333}
3334
Geoff Lang496c02d2016-10-20 11:38:11 -07003335void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003336{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003337 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003338 ASSERT(buffer);
3339
Geoff Lang496c02d2016-10-20 11:38:11 -07003340 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003341}
3342
Jamie Madill876429b2017-04-20 15:46:24 -04003343void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003344{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003345 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003346 ASSERT(buffer);
3347
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003348 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003349 if (error.isError())
3350 {
Jamie Madill437fa652016-05-03 15:13:24 -04003351 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003352 return nullptr;
3353 }
3354
3355 return buffer->getMapPointer();
3356}
3357
3358GLboolean Context::unmapBuffer(GLenum target)
3359{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003360 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003361 ASSERT(buffer);
3362
3363 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003364 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003365 if (error.isError())
3366 {
Jamie Madill437fa652016-05-03 15:13:24 -04003367 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003368 return GL_FALSE;
3369 }
3370
3371 return result;
3372}
3373
Jamie Madill876429b2017-04-20 15:46:24 -04003374void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003375{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003376 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003377 ASSERT(buffer);
3378
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003379 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003380 if (error.isError())
3381 {
Jamie Madill437fa652016-05-03 15:13:24 -04003382 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003383 return nullptr;
3384 }
3385
3386 return buffer->getMapPointer();
3387}
3388
3389void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3390{
3391 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3392}
3393
Jamie Madillad9f24e2016-02-12 09:27:24 -05003394void Context::syncStateForReadPixels()
3395{
3396 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3397}
3398
3399void Context::syncStateForTexImage()
3400{
3401 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3402}
3403
3404void Context::syncStateForClear()
3405{
3406 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3407}
3408
3409void Context::syncStateForBlit()
3410{
3411 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3412}
3413
Jamie Madillc20ab272016-06-09 07:20:46 -07003414void Context::activeTexture(GLenum texture)
3415{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003416 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003417}
3418
Jamie Madill876429b2017-04-20 15:46:24 -04003419void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003420{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003421 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003422}
3423
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003424void Context::blendEquation(GLenum mode)
3425{
3426 mGLState.setBlendEquation(mode, mode);
3427}
3428
Jamie Madillc20ab272016-06-09 07:20:46 -07003429void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3430{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003431 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003432}
3433
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003434void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3435{
3436 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3437}
3438
Jamie Madillc20ab272016-06-09 07:20:46 -07003439void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3440{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003441 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003442}
3443
Jamie Madill876429b2017-04-20 15:46:24 -04003444void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003445{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003446 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003447}
3448
Jamie Madill876429b2017-04-20 15:46:24 -04003449void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003450{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003451 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003452}
3453
3454void Context::clearStencil(GLint s)
3455{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003456 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003457}
3458
3459void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3460{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003461 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003462}
3463
3464void Context::cullFace(GLenum mode)
3465{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003466 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003467}
3468
3469void Context::depthFunc(GLenum func)
3470{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003471 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003472}
3473
3474void Context::depthMask(GLboolean flag)
3475{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003476 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003477}
3478
Jamie Madill876429b2017-04-20 15:46:24 -04003479void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003480{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003481 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003482}
3483
3484void Context::disable(GLenum cap)
3485{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003486 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003487}
3488
3489void Context::disableVertexAttribArray(GLuint index)
3490{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003491 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003492}
3493
3494void Context::enable(GLenum cap)
3495{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003496 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003497}
3498
3499void Context::enableVertexAttribArray(GLuint index)
3500{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003501 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003502}
3503
3504void Context::frontFace(GLenum mode)
3505{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003506 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003507}
3508
3509void Context::hint(GLenum target, GLenum mode)
3510{
3511 switch (target)
3512 {
3513 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003514 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003515 break;
3516
3517 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003518 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003519 break;
3520
3521 default:
3522 UNREACHABLE();
3523 return;
3524 }
3525}
3526
3527void Context::lineWidth(GLfloat width)
3528{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003529 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003530}
3531
3532void Context::pixelStorei(GLenum pname, GLint param)
3533{
3534 switch (pname)
3535 {
3536 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003537 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003538 break;
3539
3540 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003541 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003542 break;
3543
3544 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003545 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003546 break;
3547
3548 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003549 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003550 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003551 break;
3552
3553 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003554 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003555 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003556 break;
3557
3558 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003559 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003560 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003561 break;
3562
3563 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003564 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003565 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003566 break;
3567
3568 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003569 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003570 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003571 break;
3572
3573 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003574 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003575 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003576 break;
3577
3578 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003579 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003580 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003581 break;
3582
3583 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003584 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003585 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003586 break;
3587
3588 default:
3589 UNREACHABLE();
3590 return;
3591 }
3592}
3593
3594void Context::polygonOffset(GLfloat factor, GLfloat units)
3595{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003596 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003597}
3598
Jamie Madill876429b2017-04-20 15:46:24 -04003599void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003600{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003601 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003602}
3603
3604void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3605{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003606 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003607}
3608
3609void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3610{
3611 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3612 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003613 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003614 }
3615
3616 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3617 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003618 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003619 }
3620}
3621
3622void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3623{
3624 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3625 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003626 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003627 }
3628
3629 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3630 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003631 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003632 }
3633}
3634
3635void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3636{
3637 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3638 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003639 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003640 }
3641
3642 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3643 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003644 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003645 }
3646}
3647
3648void Context::vertexAttrib1f(GLuint index, GLfloat x)
3649{
3650 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003651 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003652}
3653
3654void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3655{
3656 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003657 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003658}
3659
3660void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3661{
3662 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003663 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003664}
3665
3666void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3667{
3668 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003669 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003670}
3671
3672void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3673{
3674 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003675 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003676}
3677
3678void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3679{
3680 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003681 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003682}
3683
3684void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3685{
3686 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003687 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003688}
3689
3690void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3691{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003692 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003693}
3694
3695void Context::vertexAttribPointer(GLuint index,
3696 GLint size,
3697 GLenum type,
3698 GLboolean normalized,
3699 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003700 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003701{
Jamie Madill4928b7c2017-06-20 12:57:39 -04003702 mGLState.setVertexAttribState(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3703 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003704}
3705
Shao80957d92017-02-20 21:25:59 +08003706void Context::vertexAttribFormat(GLuint attribIndex,
3707 GLint size,
3708 GLenum type,
3709 GLboolean normalized,
3710 GLuint relativeOffset)
3711{
3712 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3713 relativeOffset);
3714}
3715
3716void Context::vertexAttribIFormat(GLuint attribIndex,
3717 GLint size,
3718 GLenum type,
3719 GLuint relativeOffset)
3720{
3721 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3722}
3723
3724void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3725{
3726 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3727}
3728
3729void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3730{
3731 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3732}
3733
Jamie Madillc20ab272016-06-09 07:20:46 -07003734void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3735{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003736 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003737}
3738
3739void Context::vertexAttribIPointer(GLuint index,
3740 GLint size,
3741 GLenum type,
3742 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003743 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003744{
Jamie Madill4928b7c2017-06-20 12:57:39 -04003745 mGLState.setVertexAttribState(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3746 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003747}
3748
3749void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3750{
3751 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003752 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003753}
3754
3755void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3756{
3757 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003758 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003759}
3760
3761void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3762{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003763 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003764}
3765
3766void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3767{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003768 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003769}
3770
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003771void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3772{
3773 const VertexAttribCurrentValueData &currentValues =
3774 getGLState().getVertexAttribCurrentValue(index);
3775 const VertexArray *vao = getGLState().getVertexArray();
3776 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3777 currentValues, pname, params);
3778}
3779
3780void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3781{
3782 const VertexAttribCurrentValueData &currentValues =
3783 getGLState().getVertexAttribCurrentValue(index);
3784 const VertexArray *vao = getGLState().getVertexArray();
3785 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3786 currentValues, pname, params);
3787}
3788
3789void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3790{
3791 const VertexAttribCurrentValueData &currentValues =
3792 getGLState().getVertexAttribCurrentValue(index);
3793 const VertexArray *vao = getGLState().getVertexArray();
3794 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3795 currentValues, pname, params);
3796}
3797
3798void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3799{
3800 const VertexAttribCurrentValueData &currentValues =
3801 getGLState().getVertexAttribCurrentValue(index);
3802 const VertexArray *vao = getGLState().getVertexArray();
3803 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3804 currentValues, pname, params);
3805}
3806
Jamie Madill876429b2017-04-20 15:46:24 -04003807void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003808{
3809 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3810 QueryVertexAttribPointerv(attrib, pname, pointer);
3811}
3812
Jamie Madillc20ab272016-06-09 07:20:46 -07003813void Context::debugMessageControl(GLenum source,
3814 GLenum type,
3815 GLenum severity,
3816 GLsizei count,
3817 const GLuint *ids,
3818 GLboolean enabled)
3819{
3820 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003821 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3822 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003823}
3824
3825void Context::debugMessageInsert(GLenum source,
3826 GLenum type,
3827 GLuint id,
3828 GLenum severity,
3829 GLsizei length,
3830 const GLchar *buf)
3831{
3832 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003833 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003834}
3835
3836void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3837{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003838 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003839}
3840
3841GLuint Context::getDebugMessageLog(GLuint count,
3842 GLsizei bufSize,
3843 GLenum *sources,
3844 GLenum *types,
3845 GLuint *ids,
3846 GLenum *severities,
3847 GLsizei *lengths,
3848 GLchar *messageLog)
3849{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003850 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3851 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003852}
3853
3854void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3855{
3856 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003857 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003858}
3859
3860void Context::popDebugGroup()
3861{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003862 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003863}
3864
Jamie Madill876429b2017-04-20 15:46:24 -04003865void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003866{
3867 Buffer *buffer = mGLState.getTargetBuffer(target);
3868 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003869 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003870}
3871
Jamie Madill876429b2017-04-20 15:46:24 -04003872void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003873{
3874 if (data == nullptr)
3875 {
3876 return;
3877 }
3878
3879 Buffer *buffer = mGLState.getTargetBuffer(target);
3880 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003881 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003882}
3883
Jamie Madillef300b12016-10-07 15:12:09 -04003884void Context::attachShader(GLuint program, GLuint shader)
3885{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003886 auto programObject = mState.mShaderPrograms->getProgram(program);
3887 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003888 ASSERT(programObject && shaderObject);
3889 programObject->attachShader(shaderObject);
3890}
3891
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003892const Workarounds &Context::getWorkarounds() const
3893{
3894 return mWorkarounds;
3895}
3896
Jamie Madillb0817d12016-11-01 15:48:31 -04003897void Context::copyBufferSubData(GLenum readTarget,
3898 GLenum writeTarget,
3899 GLintptr readOffset,
3900 GLintptr writeOffset,
3901 GLsizeiptr size)
3902{
3903 // if size is zero, the copy is a successful no-op
3904 if (size == 0)
3905 {
3906 return;
3907 }
3908
3909 // TODO(jmadill): cache these.
3910 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3911 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3912
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003913 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003914}
3915
Jamie Madill01a80ee2016-11-07 12:06:18 -05003916void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3917{
3918 Program *programObject = getProgram(program);
3919 // TODO(jmadill): Re-use this from the validation if possible.
3920 ASSERT(programObject);
3921 programObject->bindAttributeLocation(index, name);
3922}
3923
3924void Context::bindBuffer(GLenum target, GLuint buffer)
3925{
3926 switch (target)
3927 {
3928 case GL_ARRAY_BUFFER:
3929 bindArrayBuffer(buffer);
3930 break;
3931 case GL_ELEMENT_ARRAY_BUFFER:
3932 bindElementArrayBuffer(buffer);
3933 break;
3934 case GL_COPY_READ_BUFFER:
3935 bindCopyReadBuffer(buffer);
3936 break;
3937 case GL_COPY_WRITE_BUFFER:
3938 bindCopyWriteBuffer(buffer);
3939 break;
3940 case GL_PIXEL_PACK_BUFFER:
3941 bindPixelPackBuffer(buffer);
3942 break;
3943 case GL_PIXEL_UNPACK_BUFFER:
3944 bindPixelUnpackBuffer(buffer);
3945 break;
3946 case GL_UNIFORM_BUFFER:
3947 bindGenericUniformBuffer(buffer);
3948 break;
3949 case GL_TRANSFORM_FEEDBACK_BUFFER:
3950 bindGenericTransformFeedbackBuffer(buffer);
3951 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003952 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003953 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003954 break;
3955 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003956 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003957 break;
3958 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003959 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003960 break;
3961 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003962 if (buffer != 0)
3963 {
3964 // Binding buffers to this binding point is not implemented yet.
3965 UNIMPLEMENTED();
3966 }
Geoff Lang3b573612016-10-31 14:08:10 -04003967 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003968
3969 default:
3970 UNREACHABLE();
3971 break;
3972 }
3973}
3974
Jiajia Qin6eafb042016-12-27 17:04:07 +08003975void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3976{
3977 bindBufferRange(target, index, buffer, 0, 0);
3978}
3979
3980void Context::bindBufferRange(GLenum target,
3981 GLuint index,
3982 GLuint buffer,
3983 GLintptr offset,
3984 GLsizeiptr size)
3985{
3986 switch (target)
3987 {
3988 case GL_TRANSFORM_FEEDBACK_BUFFER:
3989 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3990 bindGenericTransformFeedbackBuffer(buffer);
3991 break;
3992 case GL_UNIFORM_BUFFER:
3993 bindIndexedUniformBuffer(buffer, index, offset, size);
3994 bindGenericUniformBuffer(buffer);
3995 break;
3996 case GL_ATOMIC_COUNTER_BUFFER:
3997 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
3998 bindGenericAtomicCounterBuffer(buffer);
3999 break;
4000 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004001 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4002 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004003 break;
4004 default:
4005 UNREACHABLE();
4006 break;
4007 }
4008}
4009
Jamie Madill01a80ee2016-11-07 12:06:18 -05004010void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4011{
4012 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4013 {
4014 bindReadFramebuffer(framebuffer);
4015 }
4016
4017 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4018 {
4019 bindDrawFramebuffer(framebuffer);
4020 }
4021}
4022
4023void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4024{
4025 ASSERT(target == GL_RENDERBUFFER);
4026 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004027 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004028 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004029}
4030
JiangYizhoubddc46b2016-12-09 09:50:51 +08004031void Context::texStorage2DMultisample(GLenum target,
4032 GLsizei samples,
4033 GLenum internalformat,
4034 GLsizei width,
4035 GLsizei height,
4036 GLboolean fixedsamplelocations)
4037{
4038 Extents size(width, height, 1);
4039 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004040 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004041 fixedsamplelocations));
4042}
4043
4044void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4045{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004046 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004047 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4048
4049 switch (pname)
4050 {
4051 case GL_SAMPLE_POSITION:
4052 handleError(framebuffer->getSamplePosition(index, val));
4053 break;
4054 default:
4055 UNREACHABLE();
4056 }
4057}
4058
Jamie Madille8fb6402017-02-14 17:56:40 -05004059void Context::renderbufferStorage(GLenum target,
4060 GLenum internalformat,
4061 GLsizei width,
4062 GLsizei height)
4063{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004064 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4065 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4066
Jamie Madille8fb6402017-02-14 17:56:40 -05004067 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004068 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004069}
4070
4071void Context::renderbufferStorageMultisample(GLenum target,
4072 GLsizei samples,
4073 GLenum internalformat,
4074 GLsizei width,
4075 GLsizei height)
4076{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004077 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4078 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004079
4080 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004081 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004082 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004083}
4084
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004085void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4086{
4087 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004088 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004089}
4090
JiangYizhoue18e6392017-02-20 10:32:23 +08004091void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4092{
4093 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4094 QueryFramebufferParameteriv(framebuffer, pname, params);
4095}
4096
4097void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4098{
4099 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4100 SetFramebufferParameteri(framebuffer, pname, param);
4101}
4102
Jamie Madille14951e2017-03-09 18:55:16 -05004103Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4104{
4105 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004107 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004108 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004109 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004110}
4111
Xinghua Cao2b396592017-03-29 15:36:04 +08004112void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4113{
4114 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4115 {
4116 return;
4117 }
4118
Jamie Madillfe548342017-06-19 11:13:24 -04004119 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004120}
4121
JiangYizhou165361c2017-06-07 14:56:57 +08004122void Context::texStorage2D(GLenum target,
4123 GLsizei levels,
4124 GLenum internalFormat,
4125 GLsizei width,
4126 GLsizei height)
4127{
4128 Extents size(width, height, 1);
4129 Texture *texture = getTargetTexture(target);
4130 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4131}
4132
4133void Context::texStorage3D(GLenum target,
4134 GLsizei levels,
4135 GLenum internalFormat,
4136 GLsizei width,
4137 GLsizei height,
4138 GLsizei depth)
4139{
4140 Extents size(width, height, depth);
4141 Texture *texture = getTargetTexture(target);
4142 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4143}
4144
Jamie Madillc1d770e2017-04-13 17:31:24 -04004145GLenum Context::checkFramebufferStatus(GLenum target)
4146{
4147 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4148 ASSERT(framebuffer);
4149
4150 return framebuffer->checkStatus(this);
4151}
4152
4153void Context::compileShader(GLuint shader)
4154{
4155 Shader *shaderObject = GetValidShader(this, shader);
4156 if (!shaderObject)
4157 {
4158 return;
4159 }
4160 shaderObject->compile(this);
4161}
4162
4163void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4164{
4165 for (int i = 0; i < n; i++)
4166 {
4167 deleteBuffer(buffers[i]);
4168 }
4169}
4170
4171void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4172{
4173 for (int i = 0; i < n; i++)
4174 {
4175 if (framebuffers[i] != 0)
4176 {
4177 deleteFramebuffer(framebuffers[i]);
4178 }
4179 }
4180}
4181
4182void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4183{
4184 for (int i = 0; i < n; i++)
4185 {
4186 deleteRenderbuffer(renderbuffers[i]);
4187 }
4188}
4189
4190void Context::deleteTextures(GLsizei n, const GLuint *textures)
4191{
4192 for (int i = 0; i < n; i++)
4193 {
4194 if (textures[i] != 0)
4195 {
4196 deleteTexture(textures[i]);
4197 }
4198 }
4199}
4200
4201void Context::detachShader(GLuint program, GLuint shader)
4202{
4203 Program *programObject = getProgram(program);
4204 ASSERT(programObject);
4205
4206 Shader *shaderObject = getShader(shader);
4207 ASSERT(shaderObject);
4208
4209 programObject->detachShader(this, shaderObject);
4210}
4211
4212void Context::genBuffers(GLsizei n, GLuint *buffers)
4213{
4214 for (int i = 0; i < n; i++)
4215 {
4216 buffers[i] = createBuffer();
4217 }
4218}
4219
4220void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4221{
4222 for (int i = 0; i < n; i++)
4223 {
4224 framebuffers[i] = createFramebuffer();
4225 }
4226}
4227
4228void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4229{
4230 for (int i = 0; i < n; i++)
4231 {
4232 renderbuffers[i] = createRenderbuffer();
4233 }
4234}
4235
4236void Context::genTextures(GLsizei n, GLuint *textures)
4237{
4238 for (int i = 0; i < n; i++)
4239 {
4240 textures[i] = createTexture();
4241 }
4242}
4243
4244void Context::getActiveAttrib(GLuint program,
4245 GLuint index,
4246 GLsizei bufsize,
4247 GLsizei *length,
4248 GLint *size,
4249 GLenum *type,
4250 GLchar *name)
4251{
4252 Program *programObject = getProgram(program);
4253 ASSERT(programObject);
4254 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4255}
4256
4257void Context::getActiveUniform(GLuint program,
4258 GLuint index,
4259 GLsizei bufsize,
4260 GLsizei *length,
4261 GLint *size,
4262 GLenum *type,
4263 GLchar *name)
4264{
4265 Program *programObject = getProgram(program);
4266 ASSERT(programObject);
4267 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4268}
4269
4270void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4271{
4272 Program *programObject = getProgram(program);
4273 ASSERT(programObject);
4274 programObject->getAttachedShaders(maxcount, count, shaders);
4275}
4276
4277GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4278{
4279 Program *programObject = getProgram(program);
4280 ASSERT(programObject);
4281 return programObject->getAttributeLocation(name);
4282}
4283
4284void Context::getBooleanv(GLenum pname, GLboolean *params)
4285{
4286 GLenum nativeType;
4287 unsigned int numParams = 0;
4288 getQueryParameterInfo(pname, &nativeType, &numParams);
4289
4290 if (nativeType == GL_BOOL)
4291 {
4292 getBooleanvImpl(pname, params);
4293 }
4294 else
4295 {
4296 CastStateValues(this, nativeType, pname, numParams, params);
4297 }
4298}
4299
4300void Context::getFloatv(GLenum pname, GLfloat *params)
4301{
4302 GLenum nativeType;
4303 unsigned int numParams = 0;
4304 getQueryParameterInfo(pname, &nativeType, &numParams);
4305
4306 if (nativeType == GL_FLOAT)
4307 {
4308 getFloatvImpl(pname, params);
4309 }
4310 else
4311 {
4312 CastStateValues(this, nativeType, pname, numParams, params);
4313 }
4314}
4315
4316void Context::getIntegerv(GLenum pname, GLint *params)
4317{
4318 GLenum nativeType;
4319 unsigned int numParams = 0;
4320 getQueryParameterInfo(pname, &nativeType, &numParams);
4321
4322 if (nativeType == GL_INT)
4323 {
4324 getIntegervImpl(pname, params);
4325 }
4326 else
4327 {
4328 CastStateValues(this, nativeType, pname, numParams, params);
4329 }
4330}
4331
4332void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4333{
4334 Program *programObject = getProgram(program);
4335 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004336 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004337}
4338
Jamie Madillbe849e42017-05-02 15:49:00 -04004339void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004340{
4341 Program *programObject = getProgram(program);
4342 ASSERT(programObject);
4343 programObject->getInfoLog(bufsize, length, infolog);
4344}
4345
4346void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4347{
4348 Shader *shaderObject = getShader(shader);
4349 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004350 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004351}
4352
4353void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4354{
4355 Shader *shaderObject = getShader(shader);
4356 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004357 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004358}
4359
4360void Context::getShaderPrecisionFormat(GLenum shadertype,
4361 GLenum precisiontype,
4362 GLint *range,
4363 GLint *precision)
4364{
4365 // TODO(jmadill): Compute shaders.
4366
4367 switch (shadertype)
4368 {
4369 case GL_VERTEX_SHADER:
4370 switch (precisiontype)
4371 {
4372 case GL_LOW_FLOAT:
4373 mCaps.vertexLowpFloat.get(range, precision);
4374 break;
4375 case GL_MEDIUM_FLOAT:
4376 mCaps.vertexMediumpFloat.get(range, precision);
4377 break;
4378 case GL_HIGH_FLOAT:
4379 mCaps.vertexHighpFloat.get(range, precision);
4380 break;
4381
4382 case GL_LOW_INT:
4383 mCaps.vertexLowpInt.get(range, precision);
4384 break;
4385 case GL_MEDIUM_INT:
4386 mCaps.vertexMediumpInt.get(range, precision);
4387 break;
4388 case GL_HIGH_INT:
4389 mCaps.vertexHighpInt.get(range, precision);
4390 break;
4391
4392 default:
4393 UNREACHABLE();
4394 return;
4395 }
4396 break;
4397
4398 case GL_FRAGMENT_SHADER:
4399 switch (precisiontype)
4400 {
4401 case GL_LOW_FLOAT:
4402 mCaps.fragmentLowpFloat.get(range, precision);
4403 break;
4404 case GL_MEDIUM_FLOAT:
4405 mCaps.fragmentMediumpFloat.get(range, precision);
4406 break;
4407 case GL_HIGH_FLOAT:
4408 mCaps.fragmentHighpFloat.get(range, precision);
4409 break;
4410
4411 case GL_LOW_INT:
4412 mCaps.fragmentLowpInt.get(range, precision);
4413 break;
4414 case GL_MEDIUM_INT:
4415 mCaps.fragmentMediumpInt.get(range, precision);
4416 break;
4417 case GL_HIGH_INT:
4418 mCaps.fragmentHighpInt.get(range, precision);
4419 break;
4420
4421 default:
4422 UNREACHABLE();
4423 return;
4424 }
4425 break;
4426
4427 default:
4428 UNREACHABLE();
4429 return;
4430 }
4431}
4432
4433void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4434{
4435 Shader *shaderObject = getShader(shader);
4436 ASSERT(shaderObject);
4437 shaderObject->getSource(bufsize, length, source);
4438}
4439
4440void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4441{
4442 Program *programObject = getProgram(program);
4443 ASSERT(programObject);
4444 programObject->getUniformfv(location, params);
4445}
4446
4447void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4448{
4449 Program *programObject = getProgram(program);
4450 ASSERT(programObject);
4451 programObject->getUniformiv(location, params);
4452}
4453
4454GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4455{
4456 Program *programObject = getProgram(program);
4457 ASSERT(programObject);
4458 return programObject->getUniformLocation(name);
4459}
4460
4461GLboolean Context::isBuffer(GLuint buffer)
4462{
4463 if (buffer == 0)
4464 {
4465 return GL_FALSE;
4466 }
4467
4468 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4469}
4470
4471GLboolean Context::isEnabled(GLenum cap)
4472{
4473 return mGLState.getEnableFeature(cap);
4474}
4475
4476GLboolean Context::isFramebuffer(GLuint framebuffer)
4477{
4478 if (framebuffer == 0)
4479 {
4480 return GL_FALSE;
4481 }
4482
4483 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4484}
4485
4486GLboolean Context::isProgram(GLuint program)
4487{
4488 if (program == 0)
4489 {
4490 return GL_FALSE;
4491 }
4492
4493 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4494}
4495
4496GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4497{
4498 if (renderbuffer == 0)
4499 {
4500 return GL_FALSE;
4501 }
4502
4503 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4504}
4505
4506GLboolean Context::isShader(GLuint shader)
4507{
4508 if (shader == 0)
4509 {
4510 return GL_FALSE;
4511 }
4512
4513 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4514}
4515
4516GLboolean Context::isTexture(GLuint texture)
4517{
4518 if (texture == 0)
4519 {
4520 return GL_FALSE;
4521 }
4522
4523 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4524}
4525
4526void Context::linkProgram(GLuint program)
4527{
4528 Program *programObject = getProgram(program);
4529 ASSERT(programObject);
4530 handleError(programObject->link(this));
4531}
4532
4533void Context::releaseShaderCompiler()
4534{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004535 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004536}
4537
4538void Context::shaderBinary(GLsizei n,
4539 const GLuint *shaders,
4540 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004541 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004542 GLsizei length)
4543{
4544 // No binary shader formats are supported.
4545 UNIMPLEMENTED();
4546}
4547
4548void Context::shaderSource(GLuint shader,
4549 GLsizei count,
4550 const GLchar *const *string,
4551 const GLint *length)
4552{
4553 Shader *shaderObject = getShader(shader);
4554 ASSERT(shaderObject);
4555 shaderObject->setSource(count, string, length);
4556}
4557
4558void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4559{
4560 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4561}
4562
4563void Context::stencilMask(GLuint mask)
4564{
4565 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4566}
4567
4568void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4569{
4570 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4571}
4572
4573void Context::uniform1f(GLint location, GLfloat x)
4574{
4575 Program *program = mGLState.getProgram();
4576 program->setUniform1fv(location, 1, &x);
4577}
4578
4579void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4580{
4581 Program *program = mGLState.getProgram();
4582 program->setUniform1fv(location, count, v);
4583}
4584
4585void Context::uniform1i(GLint location, GLint x)
4586{
4587 Program *program = mGLState.getProgram();
4588 program->setUniform1iv(location, 1, &x);
4589}
4590
4591void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4592{
4593 Program *program = mGLState.getProgram();
4594 program->setUniform1iv(location, count, v);
4595}
4596
4597void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4598{
4599 GLfloat xy[2] = {x, y};
4600 Program *program = mGLState.getProgram();
4601 program->setUniform2fv(location, 1, xy);
4602}
4603
4604void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4605{
4606 Program *program = mGLState.getProgram();
4607 program->setUniform2fv(location, count, v);
4608}
4609
4610void Context::uniform2i(GLint location, GLint x, GLint y)
4611{
4612 GLint xy[2] = {x, y};
4613 Program *program = mGLState.getProgram();
4614 program->setUniform2iv(location, 1, xy);
4615}
4616
4617void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4618{
4619 Program *program = mGLState.getProgram();
4620 program->setUniform2iv(location, count, v);
4621}
4622
4623void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4624{
4625 GLfloat xyz[3] = {x, y, z};
4626 Program *program = mGLState.getProgram();
4627 program->setUniform3fv(location, 1, xyz);
4628}
4629
4630void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4631{
4632 Program *program = mGLState.getProgram();
4633 program->setUniform3fv(location, count, v);
4634}
4635
4636void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4637{
4638 GLint xyz[3] = {x, y, z};
4639 Program *program = mGLState.getProgram();
4640 program->setUniform3iv(location, 1, xyz);
4641}
4642
4643void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4644{
4645 Program *program = mGLState.getProgram();
4646 program->setUniform3iv(location, count, v);
4647}
4648
4649void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4650{
4651 GLfloat xyzw[4] = {x, y, z, w};
4652 Program *program = mGLState.getProgram();
4653 program->setUniform4fv(location, 1, xyzw);
4654}
4655
4656void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4657{
4658 Program *program = mGLState.getProgram();
4659 program->setUniform4fv(location, count, v);
4660}
4661
4662void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4663{
4664 GLint xyzw[4] = {x, y, z, w};
4665 Program *program = mGLState.getProgram();
4666 program->setUniform4iv(location, 1, xyzw);
4667}
4668
4669void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4670{
4671 Program *program = mGLState.getProgram();
4672 program->setUniform4iv(location, count, v);
4673}
4674
4675void Context::uniformMatrix2fv(GLint location,
4676 GLsizei count,
4677 GLboolean transpose,
4678 const GLfloat *value)
4679{
4680 Program *program = mGLState.getProgram();
4681 program->setUniformMatrix2fv(location, count, transpose, value);
4682}
4683
4684void Context::uniformMatrix3fv(GLint location,
4685 GLsizei count,
4686 GLboolean transpose,
4687 const GLfloat *value)
4688{
4689 Program *program = mGLState.getProgram();
4690 program->setUniformMatrix3fv(location, count, transpose, value);
4691}
4692
4693void Context::uniformMatrix4fv(GLint location,
4694 GLsizei count,
4695 GLboolean transpose,
4696 const GLfloat *value)
4697{
4698 Program *program = mGLState.getProgram();
4699 program->setUniformMatrix4fv(location, count, transpose, value);
4700}
4701
4702void Context::validateProgram(GLuint program)
4703{
4704 Program *programObject = getProgram(program);
4705 ASSERT(programObject);
4706 programObject->validate(mCaps);
4707}
4708
Jamie Madilld04908b2017-06-09 14:15:35 -04004709void Context::getProgramBinary(GLuint program,
4710 GLsizei bufSize,
4711 GLsizei *length,
4712 GLenum *binaryFormat,
4713 void *binary)
4714{
4715 Program *programObject = getProgram(program);
4716 ASSERT(programObject != nullptr);
4717
4718 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4719}
4720
4721void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4722{
4723 Program *programObject = getProgram(program);
4724 ASSERT(programObject != nullptr);
4725
4726 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4727}
4728
Jamie Madillc29968b2016-01-20 11:17:23 -05004729} // namespace gl