blob: d42ab2f3e9d39a8a8dbfe1a5b58335db37b71a89 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madill231c7f52017-04-26 13:45:37 -040012#include <string.h>
Jamie Madillb9293972015-02-19 11:07:54 -050013#include <iterator>
14#include <sstream>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Jamie Madill948bbe52017-06-01 13:10:42 -040023#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Fence.h"
25#include "libANGLE/Framebuffer.h"
26#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050030#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050031#include "libANGLE/ResourceManager.h"
32#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050033#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050034#include "libANGLE/Texture.h"
35#include "libANGLE/TransformFeedback.h"
36#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070037#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040038#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030039#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040040#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040041#include "libANGLE/renderer/ContextImpl.h"
42#include "libANGLE/renderer/EGLImplFactory.h"
43#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000044
Geoff Langf6db0982015-08-25 13:04:00 -040045namespace
46{
47
Jamie Madillb6664922017-07-25 12:55:04 -040048#define ANGLE_HANDLE_ERR(X) \
49 handleError(X); \
50 return;
51#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR);
52
Ian Ewell3ffd78b2016-01-22 16:09:42 -050053template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050054std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030055 GLsizei numPaths,
56 const void *paths,
57 GLuint pathBase)
58{
59 std::vector<gl::Path *> ret;
60 ret.reserve(numPaths);
61
62 const auto *nameArray = static_cast<const T *>(paths);
63
64 for (GLsizei i = 0; i < numPaths; ++i)
65 {
66 const GLuint pathName = nameArray[i] + pathBase;
67
68 ret.push_back(resourceManager.getPath(pathName));
69 }
70
71 return ret;
72}
73
Geoff Lang4ddf5af2016-12-01 14:30:44 -050074std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030075 GLsizei numPaths,
76 GLenum pathNameType,
77 const void *paths,
78 GLuint pathBase)
79{
80 switch (pathNameType)
81 {
82 case GL_UNSIGNED_BYTE:
83 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_BYTE:
86 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_SHORT:
89 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_SHORT:
92 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
93
94 case GL_UNSIGNED_INT:
95 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
96
97 case GL_INT:
98 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
99 }
100
101 UNREACHABLE();
102 return std::vector<gl::Path *>();
103}
104
105template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400106gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500107{
Geoff Lang2186c382016-10-14 10:54:54 -0400108 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500109
110 switch (pname)
111 {
112 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400113 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500114 case GL_QUERY_RESULT_AVAILABLE_EXT:
115 {
116 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400117 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500118 if (!error.isError())
119 {
Geoff Lang2186c382016-10-14 10:54:54 -0400120 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500121 }
122 return error;
123 }
124 default:
125 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500126 return gl::InternalError() << "Unreachable Error";
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500127 }
128}
129
Geoff Langf6db0982015-08-25 13:04:00 -0400130void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
131{
Geoff Lang1a683462015-09-29 15:09:59 -0400132 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400133 {
134 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
135 tfBufferIndex++)
136 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400137 const gl::OffsetBindingPointer<gl::Buffer> &buffer =
Geoff Langf6db0982015-08-25 13:04:00 -0400138 transformFeedback->getIndexedBuffer(tfBufferIndex);
139 if (buffer.get() != nullptr)
140 {
141 buffer->onTransformFeedback();
142 }
143 }
144 }
145}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500146
147// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300148EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500149{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400150 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151}
152
Martin Radev1be913c2016-07-11 17:59:16 +0300153EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
154{
155 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
156}
157
Geoff Langeb66a6e2016-10-31 13:06:12 -0400158gl::Version GetClientVersion(const egl::AttributeMap &attribs)
159{
160 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
161}
162
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500163GLenum GetResetStrategy(const egl::AttributeMap &attribs)
164{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400165 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
166 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500167 switch (attrib)
168 {
169 case EGL_NO_RESET_NOTIFICATION:
170 return GL_NO_RESET_NOTIFICATION_EXT;
171 case EGL_LOSE_CONTEXT_ON_RESET:
172 return GL_LOSE_CONTEXT_ON_RESET_EXT;
173 default:
174 UNREACHABLE();
175 return GL_NONE;
176 }
177}
178
179bool GetRobustAccess(const egl::AttributeMap &attribs)
180{
Geoff Lang077f20a2016-11-01 10:08:02 -0400181 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
182 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
183 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184}
185
186bool GetDebug(const egl::AttributeMap &attribs)
187{
Geoff Lang077f20a2016-11-01 10:08:02 -0400188 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
189 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500190}
191
192bool GetNoError(const egl::AttributeMap &attribs)
193{
194 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
195}
196
Geoff Langc287ea62016-09-16 14:46:51 -0400197bool GetWebGLContext(const egl::AttributeMap &attribs)
198{
199 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
200}
201
Geoff Langf41a7152016-09-19 15:11:17 -0400202bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
203{
204 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
205}
206
Geoff Langfeb8c682017-02-13 16:07:35 -0500207bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
208{
209 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
210}
211
Martin Radev9d901792016-07-15 15:58:58 +0300212std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
213{
214 std::string labelName;
215 if (label != nullptr)
216 {
217 size_t labelLength = length < 0 ? strlen(label) : length;
218 labelName = std::string(label, labelLength);
219 }
220 return labelName;
221}
222
223void GetObjectLabelBase(const std::string &objectLabel,
224 GLsizei bufSize,
225 GLsizei *length,
226 GLchar *label)
227{
228 size_t writeLength = objectLabel.length();
229 if (label != nullptr && bufSize > 0)
230 {
231 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
232 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
233 label[writeLength] = '\0';
234 }
235
236 if (length != nullptr)
237 {
238 *length = static_cast<GLsizei>(writeLength);
239 }
240}
241
Geoff Langf6db0982015-08-25 13:04:00 -0400242} // anonymous namespace
243
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000244namespace gl
245{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000246
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400247Context::Context(rx::EGLImplFactory *implFactory,
248 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400249 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500250 TextureManager *shareTextures,
Jamie Madill32447362017-06-28 14:53:52 -0400251 MemoryProgramCache *memoryProgramCache,
Corentin Wallezc295e512017-01-27 17:47:50 -0500252 const egl::AttributeMap &attribs,
Jamie Madill948bbe52017-06-01 13:10:42 -0400253 const egl::DisplayExtensions &displayExtensions,
254 bool robustResourceInit)
Martin Radev1be913c2016-07-11 17:59:16 +0300255
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500256 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500257 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500258 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700259 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500260 mCaps,
261 mTextureCaps,
262 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500263 mLimitations,
264 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700265 mImplementation(implFactory->createContext(mState)),
Jamie Madill2f348d22017-06-05 10:50:59 -0400266 mCompiler(),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400267 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500268 mClientType(EGL_OPENGL_ES_API),
269 mHasBeenCurrent(false),
270 mContextLost(false),
271 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700272 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500273 mResetStrategy(GetResetStrategy(attribs)),
274 mRobustAccess(GetRobustAccess(attribs)),
Jamie Madill61e16b42017-06-19 11:13:23 -0400275 mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
276 mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500277 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500278 mWebGLContext(GetWebGLContext(attribs)),
Jamie Madill32447362017-06-28 14:53:52 -0400279 mMemoryProgramCache(memoryProgramCache),
Jamie Madillb3f26b92017-07-19 15:07:41 -0400280 mScratchBuffer(1000u),
281 mZeroFilledBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282{
Geoff Lang077f20a2016-11-01 10:08:02 -0400283 if (mRobustAccess)
284 {
285 UNIMPLEMENTED();
286 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000287
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500288 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700289 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400290
Jamie Madill4928b7c2017-06-20 12:57:39 -0400291 mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs),
Jamie Madillc43be722017-07-13 16:22:14 -0400292 GetClientArraysEnabled(attribs), robustResourceInit,
293 mMemoryProgramCache != nullptr);
Régis Fénéon83107972015-02-05 12:57:44 +0100294
Shannon Woods53a94a82014-06-24 15:20:36 -0400295 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400296
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000297 // [OpenGL ES 2.0.24] section 3.7 page 83:
298 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
299 // and cube map texture state vectors respectively associated with them.
300 // In order that access to these initial textures not be lost, they are treated as texture
301 // objects all of whose names are 0.
302
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400304 mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500305
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400307 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308
Geoff Langeb66a6e2016-10-31 13:06:12 -0400309 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400310 {
311 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400312 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400313 mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400314
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400315 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400316 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400317 }
Geoff Lang3b573612016-10-31 14:08:10 -0400318 if (getClientVersion() >= Version(3, 1))
319 {
320 Texture *zeroTexture2DMultisample =
321 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400322 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800323
324 bindGenericAtomicCounterBuffer(0);
325 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
326 {
327 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
328 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800329
330 bindGenericShaderStorageBuffer(0);
331 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
332 {
333 bindIndexedShaderStorageBuffer(0, i, 0, 0);
334 }
Geoff Lang3b573612016-10-31 14:08:10 -0400335 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000336
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400337 if (mExtensions.textureRectangle)
338 {
339 Texture *zeroTextureRectangle =
340 new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE);
341 mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle);
342 }
343
Ian Ewellbda75592016-04-18 17:25:54 -0400344 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
345 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400346 Texture *zeroTextureExternal =
347 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400348 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal);
Ian Ewellbda75592016-04-18 17:25:54 -0400349 }
350
Jamie Madill4928b7c2017-06-20 12:57:39 -0400351 mGLState.initializeZeroTextures(this, mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500352
Jamie Madill57a89722013-07-02 11:57:03 -0400353 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000354 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800355 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000356 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400357
Jamie Madill01a80ee2016-11-07 12:06:18 -0500358 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000359
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000360 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500361 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000362 {
363 bindIndexedUniformBuffer(0, i, 0, -1);
364 }
365
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000366 bindCopyReadBuffer(0);
367 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000368 bindPixelPackBuffer(0);
369 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000370
Geoff Langeb66a6e2016-10-31 13:06:12 -0400371 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400372 {
373 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
374 // In the initial state, a default transform feedback object is bound and treated as
375 // a transform feedback object with a name of zero. That object is bound any time
376 // BindTransformFeedback is called with id of zero
Jamie Madillf0dcb8b2017-08-26 19:05:13 -0400377 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Geoff Lang1a683462015-09-29 15:09:59 -0400378 }
Geoff Langc8058452014-02-03 12:04:11 -0500379
Jamie Madillad9f24e2016-02-12 09:27:24 -0500380 // Initialize dirty bit masks
381 // TODO(jmadill): additional ES3 state
382 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
383 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
384 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
385 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
386 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
387 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400388 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500389 // No dirty objects.
390
391 // Readpixels uses the pack state and read FBO
392 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
393 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
394 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
395 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
396 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400397 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500398 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
399
400 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
401 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
402 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
403 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
404 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
405 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
406 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
407 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
408 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
409 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
410 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
411 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
412
413 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
414 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700415 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500416 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
417 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400418
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400419 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420}
421
Jamie Madill4928b7c2017-06-20 12:57:39 -0400422egl::Error Context::onDestroy(const egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423{
Corentin Wallez80b24112015-08-25 16:41:57 -0400424 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000425 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400426 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400428 mFenceNVMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429
Corentin Wallez80b24112015-08-25 16:41:57 -0400430 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400432 if (query.second != nullptr)
433 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400434 query.second->release(this);
Geoff Langf0aa8422015-09-29 15:08:34 -0400435 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000436 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400437 mQueryMap.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438
Corentin Wallez80b24112015-08-25 16:41:57 -0400439 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400440 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400441 if (vertexArray.second)
442 {
443 vertexArray.second->onDestroy(this);
444 }
Jamie Madill57a89722013-07-02 11:57:03 -0400445 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400446 mVertexArrayMap.clear();
Jamie Madill57a89722013-07-02 11:57:03 -0400447
Corentin Wallez80b24112015-08-25 16:41:57 -0400448 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500449 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500450 if (transformFeedback.second != nullptr)
451 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500452 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500453 }
Geoff Langc8058452014-02-03 12:04:11 -0500454 }
Jamie Madill96a483b2017-06-27 16:49:21 -0400455 mTransformFeedbackMap.clear();
Geoff Langc8058452014-02-03 12:04:11 -0500456
Jamie Madilldedd7b92014-11-05 16:30:36 -0500457 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400458 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400459 zeroTexture.second->onDestroy(this);
460 zeroTexture.second.set(this, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400461 }
462 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463
Corentin Wallezccab69d2017-01-27 16:57:15 -0500464 SafeDelete(mSurfacelessFramebuffer);
465
Jamie Madill4928b7c2017-06-20 12:57:39 -0400466 ANGLE_TRY(releaseSurface(display));
Jamie Madill2f348d22017-06-05 10:50:59 -0400467 releaseShaderCompiler();
Jamie Madill6c1f6712017-02-14 19:08:04 -0500468
Jamie Madill4928b7c2017-06-20 12:57:39 -0400469 mGLState.reset(this);
470
Jamie Madill6c1f6712017-02-14 19:08:04 -0500471 mState.mBuffers->release(this);
472 mState.mShaderPrograms->release(this);
473 mState.mTextures->release(this);
474 mState.mRenderbuffers->release(this);
475 mState.mSamplers->release(this);
476 mState.mFenceSyncs->release(this);
477 mState.mPaths->release(this);
478 mState.mFramebuffers->release(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400479
480 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000481}
482
Jamie Madill70ee0f62017-02-06 16:04:20 -0500483Context::~Context()
484{
485}
486
Jamie Madill4928b7c2017-06-20 12:57:39 -0400487egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488{
Jamie Madill61e16b42017-06-19 11:13:23 -0400489 mCurrentDisplay = display;
490
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000491 if (!mHasBeenCurrent)
492 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500494 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400495 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000496
Corentin Wallezc295e512017-01-27 17:47:50 -0500497 int width = 0;
498 int height = 0;
499 if (surface != nullptr)
500 {
501 width = surface->getWidth();
502 height = surface->getHeight();
503 }
504
505 mGLState.setViewportParams(0, 0, width, height);
506 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000507
508 mHasBeenCurrent = true;
509 }
510
Jamie Madill1b94d432015-08-07 13:23:23 -0400511 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700512 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400513
Jamie Madill4928b7c2017-06-20 12:57:39 -0400514 ANGLE_TRY(releaseSurface(display));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500515
516 Framebuffer *newDefault = nullptr;
517 if (surface != nullptr)
518 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400519 ANGLE_TRY(surface->setIsCurrent(this, true));
Corentin Wallezccab69d2017-01-27 16:57:15 -0500520 mCurrentSurface = surface;
521 newDefault = surface->getDefaultFramebuffer();
522 }
523 else
524 {
525 if (mSurfacelessFramebuffer == nullptr)
526 {
527 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
528 }
529
530 newDefault = mSurfacelessFramebuffer;
531 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000532
Corentin Wallez37c39792015-08-20 14:19:46 -0400533 // Update default framebuffer, the binding of the previous default
534 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400535 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700536 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400537 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700538 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400539 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700540 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400541 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700542 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400543 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500544 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400545 }
Ian Ewell292f0052016-02-04 10:37:32 -0500546
547 // Notify the renderer of a context switch
Jamie Madill4928b7c2017-06-20 12:57:39 -0400548 mImplementation->onMakeCurrent(this);
549 return egl::NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000550}
551
Jamie Madill4928b7c2017-06-20 12:57:39 -0400552egl::Error Context::releaseSurface(const egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400553{
Corentin Wallez37c39792015-08-20 14:19:46 -0400554 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500555 Framebuffer *currentDefault = nullptr;
556 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400557 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500558 currentDefault = mCurrentSurface->getDefaultFramebuffer();
559 }
560 else if (mSurfacelessFramebuffer != nullptr)
561 {
562 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400563 }
564
Corentin Wallezc295e512017-01-27 17:47:50 -0500565 if (mGLState.getReadFramebuffer() == currentDefault)
566 {
567 mGLState.setReadFramebufferBinding(nullptr);
568 }
569 if (mGLState.getDrawFramebuffer() == currentDefault)
570 {
571 mGLState.setDrawFramebufferBinding(nullptr);
572 }
573 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
574
575 if (mCurrentSurface)
576 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400577 ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false));
Corentin Wallezc295e512017-01-27 17:47:50 -0500578 mCurrentSurface = nullptr;
579 }
Jamie Madill4928b7c2017-06-20 12:57:39 -0400580
581 return egl::NoError();
Jamie Madill77a72f62015-04-14 11:18:32 -0400582}
583
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000584GLuint Context::createBuffer()
585{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500586 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587}
588
589GLuint Context::createProgram()
590{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500591 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592}
593
594GLuint Context::createShader(GLenum type)
595{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500596 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597}
598
599GLuint Context::createTexture()
600{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500601 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000602}
603
604GLuint Context::createRenderbuffer()
605{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500606 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000607}
608
Sami Väisänene45e53b2016-05-25 10:36:04 +0300609GLuint Context::createPaths(GLsizei range)
610{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500611 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300612 if (resultOrError.isError())
613 {
614 handleError(resultOrError.getError());
615 return 0;
616 }
617 return resultOrError.getResult();
618}
619
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620// Returns an unused framebuffer name
621GLuint Context::createFramebuffer()
622{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500623 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000624}
625
Jamie Madill33dc8432013-07-26 11:55:05 -0400626GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000627{
Jamie Madill33dc8432013-07-26 11:55:05 -0400628 GLuint handle = mFenceNVHandleAllocator.allocate();
Jamie Madill96a483b2017-06-27 16:49:21 -0400629 mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630 return handle;
631}
632
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000633void Context::deleteBuffer(GLuint buffer)
634{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500635 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000636 {
637 detachBuffer(buffer);
638 }
Jamie Madill893ab082014-05-16 16:56:10 -0400639
Jamie Madill6c1f6712017-02-14 19:08:04 -0500640 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641}
642
643void Context::deleteShader(GLuint shader)
644{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500645 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000646}
647
648void Context::deleteProgram(GLuint program)
649{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500650 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000651}
652
653void Context::deleteTexture(GLuint texture)
654{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500655 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656 {
657 detachTexture(texture);
658 }
659
Jamie Madill6c1f6712017-02-14 19:08:04 -0500660 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000661}
662
663void Context::deleteRenderbuffer(GLuint renderbuffer)
664{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500665 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000666 {
667 detachRenderbuffer(renderbuffer);
668 }
Jamie Madill893ab082014-05-16 16:56:10 -0400669
Jamie Madill6c1f6712017-02-14 19:08:04 -0500670 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000671}
672
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400673void Context::deleteSync(GLsync sync)
Jamie Madillcd055f82013-07-26 11:55:15 -0400674{
675 // The spec specifies the underlying Fence object is not deleted until all current
676 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
677 // and since our API is currently designed for being called from a single thread, we can delete
678 // the fence immediately.
Jamie Madill7f0c5a42017-08-26 22:43:26 -0400679 mState.mFenceSyncs->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400680}
681
Sami Väisänene45e53b2016-05-25 10:36:04 +0300682void Context::deletePaths(GLuint first, GLsizei range)
683{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500684 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300685}
686
687bool Context::hasPathData(GLuint path) const
688{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500689 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300690 if (pathObj == nullptr)
691 return false;
692
693 return pathObj->hasPathData();
694}
695
696bool Context::hasPath(GLuint path) const
697{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500698 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300699}
700
701void Context::setPathCommands(GLuint path,
702 GLsizei numCommands,
703 const GLubyte *commands,
704 GLsizei numCoords,
705 GLenum coordType,
706 const void *coords)
707{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500708 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300709
710 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
711}
712
713void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
714{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500715 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300716
717 switch (pname)
718 {
719 case GL_PATH_STROKE_WIDTH_CHROMIUM:
720 pathObj->setStrokeWidth(value);
721 break;
722 case GL_PATH_END_CAPS_CHROMIUM:
723 pathObj->setEndCaps(static_cast<GLenum>(value));
724 break;
725 case GL_PATH_JOIN_STYLE_CHROMIUM:
726 pathObj->setJoinStyle(static_cast<GLenum>(value));
727 break;
728 case GL_PATH_MITER_LIMIT_CHROMIUM:
729 pathObj->setMiterLimit(value);
730 break;
731 case GL_PATH_STROKE_BOUND_CHROMIUM:
732 pathObj->setStrokeBound(value);
733 break;
734 default:
735 UNREACHABLE();
736 break;
737 }
738}
739
740void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
741{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500742 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300743
744 switch (pname)
745 {
746 case GL_PATH_STROKE_WIDTH_CHROMIUM:
747 *value = pathObj->getStrokeWidth();
748 break;
749 case GL_PATH_END_CAPS_CHROMIUM:
750 *value = static_cast<GLfloat>(pathObj->getEndCaps());
751 break;
752 case GL_PATH_JOIN_STYLE_CHROMIUM:
753 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
754 break;
755 case GL_PATH_MITER_LIMIT_CHROMIUM:
756 *value = pathObj->getMiterLimit();
757 break;
758 case GL_PATH_STROKE_BOUND_CHROMIUM:
759 *value = pathObj->getStrokeBound();
760 break;
761 default:
762 UNREACHABLE();
763 break;
764 }
765}
766
767void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
768{
769 mGLState.setPathStencilFunc(func, ref, mask);
770}
771
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000772void Context::deleteFramebuffer(GLuint framebuffer)
773{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500774 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000775 {
776 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000777 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500778
Jamie Madill6c1f6712017-02-14 19:08:04 -0500779 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000780}
781
Jamie Madill33dc8432013-07-26 11:55:05 -0400782void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000783{
Jamie Madill96a483b2017-06-27 16:49:21 -0400784 FenceNV *fenceObject = nullptr;
785 if (mFenceNVMap.erase(fence, &fenceObject))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000786 {
Jamie Madill96a483b2017-06-27 16:49:21 -0400787 mFenceNVHandleAllocator.release(fence);
788 delete fenceObject;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000789 }
790}
791
Geoff Lang70d0f492015-12-10 17:45:46 -0500792Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500794 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795}
796
Jamie Madill570f7c82014-07-03 10:38:54 -0400797Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500799 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800}
801
Geoff Lang70d0f492015-12-10 17:45:46 -0500802Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000803{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500804 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805}
806
Jamie Madillcd055f82013-07-26 11:55:15 -0400807FenceSync *Context::getFenceSync(GLsync handle) const
808{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500809 return mState.mFenceSyncs->getFenceSync(
810 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400811}
812
Jamie Madill57a89722013-07-02 11:57:03 -0400813VertexArray *Context::getVertexArray(GLuint handle) const
814{
Jamie Madill96a483b2017-06-27 16:49:21 -0400815 return mVertexArrayMap.query(handle);
Jamie Madill57a89722013-07-02 11:57:03 -0400816}
817
Jamie Madilldc356042013-07-19 16:36:57 -0400818Sampler *Context::getSampler(GLuint handle) const
819{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500820 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400821}
822
Geoff Langc8058452014-02-03 12:04:11 -0500823TransformFeedback *Context::getTransformFeedback(GLuint handle) const
824{
Jamie Madill96a483b2017-06-27 16:49:21 -0400825 return mTransformFeedbackMap.query(handle);
Geoff Langc8058452014-02-03 12:04:11 -0500826}
827
Geoff Lang70d0f492015-12-10 17:45:46 -0500828LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
829{
830 switch (identifier)
831 {
832 case GL_BUFFER:
833 return getBuffer(name);
834 case GL_SHADER:
835 return getShader(name);
836 case GL_PROGRAM:
837 return getProgram(name);
838 case GL_VERTEX_ARRAY:
839 return getVertexArray(name);
840 case GL_QUERY:
841 return getQuery(name);
842 case GL_TRANSFORM_FEEDBACK:
843 return getTransformFeedback(name);
844 case GL_SAMPLER:
845 return getSampler(name);
846 case GL_TEXTURE:
847 return getTexture(name);
848 case GL_RENDERBUFFER:
849 return getRenderbuffer(name);
850 case GL_FRAMEBUFFER:
851 return getFramebuffer(name);
852 default:
853 UNREACHABLE();
854 return nullptr;
855 }
856}
857
858LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
859{
860 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
861}
862
Martin Radev9d901792016-07-15 15:58:58 +0300863void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
864{
865 LabeledObject *object = getLabeledObject(identifier, name);
866 ASSERT(object != nullptr);
867
868 std::string labelName = GetObjectLabelFromPointer(length, label);
869 object->setLabel(labelName);
870}
871
872void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
873{
874 LabeledObject *object = getLabeledObjectFromPtr(ptr);
875 ASSERT(object != nullptr);
876
877 std::string labelName = GetObjectLabelFromPointer(length, label);
878 object->setLabel(labelName);
879}
880
881void Context::getObjectLabel(GLenum identifier,
882 GLuint name,
883 GLsizei bufSize,
884 GLsizei *length,
885 GLchar *label) const
886{
887 LabeledObject *object = getLabeledObject(identifier, name);
888 ASSERT(object != nullptr);
889
890 const std::string &objectLabel = object->getLabel();
891 GetObjectLabelBase(objectLabel, bufSize, length, label);
892}
893
894void Context::getObjectPtrLabel(const void *ptr,
895 GLsizei bufSize,
896 GLsizei *length,
897 GLchar *label) const
898{
899 LabeledObject *object = getLabeledObjectFromPtr(ptr);
900 ASSERT(object != nullptr);
901
902 const std::string &objectLabel = object->getLabel();
903 GetObjectLabelBase(objectLabel, bufSize, length, label);
904}
905
Jamie Madilldc356042013-07-19 16:36:57 -0400906bool Context::isSampler(GLuint samplerName) const
907{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500908 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400909}
910
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500911void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000912{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500913 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400914 mGLState.setArrayBufferBinding(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000915}
916
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800917void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
918{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500919 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400920 mGLState.setDrawIndirectBufferBinding(this, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800921}
922
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500923void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000924{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500925 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400926 mGLState.setElementArrayBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000927}
928
Jamie Madilldedd7b92014-11-05 16:30:36 -0500929void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000930{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500931 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000932
Jamie Madilldedd7b92014-11-05 16:30:36 -0500933 if (handle == 0)
934 {
935 texture = mZeroTextures[target].get();
936 }
937 else
938 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500939 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500940 }
941
942 ASSERT(texture);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400943 mGLState.setSamplerTexture(this, target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000944}
945
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500946void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000947{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500948 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
949 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700950 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000951}
952
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500953void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500955 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
956 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700957 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958}
959
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500960void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400961{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500962 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700963 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400964}
965
Shao80957d92017-02-20 21:25:59 +0800966void Context::bindVertexBuffer(GLuint bindingIndex,
967 GLuint bufferHandle,
968 GLintptr offset,
969 GLsizei stride)
970{
971 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400972 mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +0800973}
974
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500975void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400976{
Geoff Lang76b10c92014-09-05 16:28:14 -0400977 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400978 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500979 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400980 mGLState.setSamplerBinding(this, textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400981}
982
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800983void Context::bindImageTexture(GLuint unit,
984 GLuint texture,
985 GLint level,
986 GLboolean layered,
987 GLint layer,
988 GLenum access,
989 GLenum format)
990{
991 Texture *tex = mState.mTextures->getTexture(texture);
992 mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
993}
994
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500995void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000996{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500997 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400998 mGLState.setGenericUniformBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000999}
1000
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001001void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1002 GLuint index,
1003 GLintptr offset,
1004 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001005{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001006 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001007 mGLState.setIndexedUniformBufferBinding(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001008}
1009
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001010void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001011{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001012 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001013 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001014}
1015
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001016void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1017 GLuint index,
1018 GLintptr offset,
1019 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001020{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001021 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001022 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(this, index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001023}
1024
Jiajia Qin6eafb042016-12-27 17:04:07 +08001025void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1026{
1027 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001028 mGLState.setGenericAtomicCounterBufferBinding(this, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001029}
1030
1031void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1032 GLuint index,
1033 GLintptr offset,
1034 GLsizeiptr size)
1035{
1036 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001037 mGLState.setIndexedAtomicCounterBufferBinding(this, index, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001038}
1039
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001040void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1041{
1042 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001043 mGLState.setGenericShaderStorageBufferBinding(this, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001044}
1045
1046void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1047 GLuint index,
1048 GLintptr offset,
1049 GLsizeiptr size)
1050{
1051 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001052 mGLState.setIndexedShaderStorageBufferBinding(this, index, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001053}
1054
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001055void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001056{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001057 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001058 mGLState.setCopyReadBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001059}
1060
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001061void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001062{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001063 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001064 mGLState.setCopyWriteBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001065}
1066
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001067void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001068{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001069 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001070 mGLState.setPixelPackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001071}
1072
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001073void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001074{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001075 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001076 mGLState.setPixelUnpackBufferBinding(this, buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001077}
1078
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001079void Context::useProgram(GLuint program)
1080{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001081 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001082}
1083
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001084void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001085{
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04001086 ASSERT(target == GL_TRANSFORM_FEEDBACK);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001087 TransformFeedback *transformFeedback =
1088 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001089 mGLState.setTransformFeedbackBinding(this, transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001090}
1091
Jamie Madillf0e04492017-08-26 15:28:42 -04001092void Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001093{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001094 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001095 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001096
Geoff Lang5aad9672014-09-08 11:10:42 -04001097 // begin query
Jamie Madillf0e04492017-08-26 15:28:42 -04001098 ANGLE_CONTEXT_TRY(queryObject->begin());
Geoff Lang5aad9672014-09-08 11:10:42 -04001099
1100 // set query as active for specified target only if begin succeeded
Jamie Madill4928b7c2017-06-20 12:57:39 -04001101 mGLState.setActiveQuery(this, target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001102}
1103
Jamie Madillf0e04492017-08-26 15:28:42 -04001104void Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001105{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001106 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001107 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001108
Jamie Madillf0e04492017-08-26 15:28:42 -04001109 handleError(queryObject->end());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001110
Geoff Lang5aad9672014-09-08 11:10:42 -04001111 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madill4928b7c2017-06-20 12:57:39 -04001112 mGLState.setActiveQuery(this, target, nullptr);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001113}
1114
Jamie Madillf0e04492017-08-26 15:28:42 -04001115void Context::queryCounter(GLuint id, GLenum target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001116{
1117 ASSERT(target == GL_TIMESTAMP_EXT);
1118
1119 Query *queryObject = getQuery(id, true, target);
1120 ASSERT(queryObject);
1121
Jamie Madillf0e04492017-08-26 15:28:42 -04001122 handleError(queryObject->queryCounter());
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001123}
1124
1125void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1126{
1127 switch (pname)
1128 {
1129 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001130 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001131 break;
1132 case GL_QUERY_COUNTER_BITS_EXT:
1133 switch (target)
1134 {
1135 case GL_TIME_ELAPSED_EXT:
1136 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1137 break;
1138 case GL_TIMESTAMP_EXT:
1139 params[0] = getExtensions().queryCounterBitsTimestamp;
1140 break;
1141 default:
1142 UNREACHABLE();
1143 params[0] = 0;
1144 break;
1145 }
1146 break;
1147 default:
1148 UNREACHABLE();
1149 return;
1150 }
1151}
1152
Geoff Lang2186c382016-10-14 10:54:54 -04001153void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001154{
Geoff Lang2186c382016-10-14 10:54:54 -04001155 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001156}
1157
Geoff Lang2186c382016-10-14 10:54:54 -04001158void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001159{
Geoff Lang2186c382016-10-14 10:54:54 -04001160 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001161}
1162
Geoff Lang2186c382016-10-14 10:54:54 -04001163void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001164{
Geoff Lang2186c382016-10-14 10:54:54 -04001165 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001166}
1167
Geoff Lang2186c382016-10-14 10:54:54 -04001168void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001169{
Geoff Lang2186c382016-10-14 10:54:54 -04001170 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001171}
1172
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001173Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001175 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001176}
1177
Jamie Madill2f348d22017-06-05 10:50:59 -04001178FenceNV *Context::getFenceNV(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179{
Jamie Madill96a483b2017-06-27 16:49:21 -04001180 return mFenceNVMap.query(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181}
1182
Jamie Madill2f348d22017-06-05 10:50:59 -04001183Query *Context::getQuery(GLuint handle, bool create, GLenum type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184{
Jamie Madill96a483b2017-06-27 16:49:21 -04001185 if (!mQueryMap.contains(handle))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001187 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001188 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001189
1190 Query *query = mQueryMap.query(handle);
1191 if (!query && create)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001192 {
Jamie Madill96a483b2017-06-27 16:49:21 -04001193 query = new Query(mImplementation->createQuery(type), handle);
1194 query->addRef();
1195 mQueryMap.assign(handle, query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001196 }
Jamie Madill96a483b2017-06-27 16:49:21 -04001197 return query;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001198}
1199
Geoff Lang70d0f492015-12-10 17:45:46 -05001200Query *Context::getQuery(GLuint handle) const
1201{
Jamie Madill96a483b2017-06-27 16:49:21 -04001202 return mQueryMap.query(handle);
Geoff Lang70d0f492015-12-10 17:45:46 -05001203}
1204
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001205Texture *Context::getTargetTexture(GLenum target) const
1206{
Ian Ewellbda75592016-04-18 17:25:54 -04001207 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001208 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001209}
1210
Geoff Lang76b10c92014-09-05 16:28:14 -04001211Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001212{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001213 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001214}
1215
Geoff Lang492a7e42014-11-05 13:27:06 -05001216Compiler *Context::getCompiler() const
1217{
Jamie Madill2f348d22017-06-05 10:50:59 -04001218 if (mCompiler.get() == nullptr)
1219 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001220 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
Jamie Madill2f348d22017-06-05 10:50:59 -04001221 }
1222 return mCompiler.get();
Geoff Lang492a7e42014-11-05 13:27:06 -05001223}
1224
Jamie Madillc1d770e2017-04-13 17:31:24 -04001225void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226{
1227 switch (pname)
1228 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001229 case GL_SHADER_COMPILER:
1230 *params = GL_TRUE;
1231 break;
1232 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1233 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1234 break;
1235 default:
1236 mGLState.getBooleanv(pname, params);
1237 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001239}
1240
Jamie Madillc1d770e2017-04-13 17:31:24 -04001241void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242{
Shannon Woods53a94a82014-06-24 15:20:36 -04001243 // Queries about context capabilities and maximums are answered by Context.
1244 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001245 switch (pname)
1246 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001247 case GL_ALIASED_LINE_WIDTH_RANGE:
1248 params[0] = mCaps.minAliasedLineWidth;
1249 params[1] = mCaps.maxAliasedLineWidth;
1250 break;
1251 case GL_ALIASED_POINT_SIZE_RANGE:
1252 params[0] = mCaps.minAliasedPointSize;
1253 params[1] = mCaps.maxAliasedPointSize;
1254 break;
1255 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1256 ASSERT(mExtensions.textureFilterAnisotropic);
1257 *params = mExtensions.maxTextureAnisotropy;
1258 break;
1259 case GL_MAX_TEXTURE_LOD_BIAS:
1260 *params = mCaps.maxLODBias;
1261 break;
1262
1263 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1264 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1265 {
1266 ASSERT(mExtensions.pathRendering);
1267 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1268 memcpy(params, m, 16 * sizeof(GLfloat));
1269 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001270 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001271
Jamie Madill231c7f52017-04-26 13:45:37 -04001272 default:
1273 mGLState.getFloatv(pname, params);
1274 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276}
1277
Jamie Madillc1d770e2017-04-13 17:31:24 -04001278void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279{
Shannon Woods53a94a82014-06-24 15:20:36 -04001280 // Queries about context capabilities and maximums are answered by Context.
1281 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001282
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001283 switch (pname)
1284 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001285 case GL_MAX_VERTEX_ATTRIBS:
1286 *params = mCaps.maxVertexAttributes;
1287 break;
1288 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1289 *params = mCaps.maxVertexUniformVectors;
1290 break;
1291 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1292 *params = mCaps.maxVertexUniformComponents;
1293 break;
1294 case GL_MAX_VARYING_VECTORS:
1295 *params = mCaps.maxVaryingVectors;
1296 break;
1297 case GL_MAX_VARYING_COMPONENTS:
1298 *params = mCaps.maxVertexOutputComponents;
1299 break;
1300 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1301 *params = mCaps.maxCombinedTextureImageUnits;
1302 break;
1303 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1304 *params = mCaps.maxVertexTextureImageUnits;
1305 break;
1306 case GL_MAX_TEXTURE_IMAGE_UNITS:
1307 *params = mCaps.maxTextureImageUnits;
1308 break;
1309 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1310 *params = mCaps.maxFragmentUniformVectors;
1311 break;
1312 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1313 *params = mCaps.maxFragmentUniformComponents;
1314 break;
1315 case GL_MAX_RENDERBUFFER_SIZE:
1316 *params = mCaps.maxRenderbufferSize;
1317 break;
1318 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1319 *params = mCaps.maxColorAttachments;
1320 break;
1321 case GL_MAX_DRAW_BUFFERS_EXT:
1322 *params = mCaps.maxDrawBuffers;
1323 break;
1324 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1325 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1326 case GL_SUBPIXEL_BITS:
1327 *params = 4;
1328 break;
1329 case GL_MAX_TEXTURE_SIZE:
1330 *params = mCaps.max2DTextureSize;
1331 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001332 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1333 *params = mCaps.maxRectangleTextureSize;
1334 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001335 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1336 *params = mCaps.maxCubeMapTextureSize;
1337 break;
1338 case GL_MAX_3D_TEXTURE_SIZE:
1339 *params = mCaps.max3DTextureSize;
1340 break;
1341 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1342 *params = mCaps.maxArrayTextureLayers;
1343 break;
1344 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1345 *params = mCaps.uniformBufferOffsetAlignment;
1346 break;
1347 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1348 *params = mCaps.maxUniformBufferBindings;
1349 break;
1350 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1351 *params = mCaps.maxVertexUniformBlocks;
1352 break;
1353 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1354 *params = mCaps.maxFragmentUniformBlocks;
1355 break;
1356 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1357 *params = mCaps.maxCombinedTextureImageUnits;
1358 break;
1359 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1360 *params = mCaps.maxVertexOutputComponents;
1361 break;
1362 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1363 *params = mCaps.maxFragmentInputComponents;
1364 break;
1365 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1366 *params = mCaps.minProgramTexelOffset;
1367 break;
1368 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1369 *params = mCaps.maxProgramTexelOffset;
1370 break;
1371 case GL_MAJOR_VERSION:
1372 *params = getClientVersion().major;
1373 break;
1374 case GL_MINOR_VERSION:
1375 *params = getClientVersion().minor;
1376 break;
1377 case GL_MAX_ELEMENTS_INDICES:
1378 *params = mCaps.maxElementsIndices;
1379 break;
1380 case GL_MAX_ELEMENTS_VERTICES:
1381 *params = mCaps.maxElementsVertices;
1382 break;
1383 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1384 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1385 break;
1386 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1387 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1388 break;
1389 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1390 *params = mCaps.maxTransformFeedbackSeparateComponents;
1391 break;
1392 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1393 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1394 break;
1395 case GL_MAX_SAMPLES_ANGLE:
1396 *params = mCaps.maxSamples;
1397 break;
1398 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001399 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001400 params[0] = mCaps.maxViewportWidth;
1401 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001402 }
1403 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001404 case GL_COMPRESSED_TEXTURE_FORMATS:
1405 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1406 params);
1407 break;
1408 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1409 *params = mResetStrategy;
1410 break;
1411 case GL_NUM_SHADER_BINARY_FORMATS:
1412 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1413 break;
1414 case GL_SHADER_BINARY_FORMATS:
1415 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1416 break;
1417 case GL_NUM_PROGRAM_BINARY_FORMATS:
1418 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1419 break;
1420 case GL_PROGRAM_BINARY_FORMATS:
1421 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1422 break;
1423 case GL_NUM_EXTENSIONS:
1424 *params = static_cast<GLint>(mExtensionStrings.size());
1425 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001426
Jamie Madill231c7f52017-04-26 13:45:37 -04001427 // GL_KHR_debug
1428 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1429 *params = mExtensions.maxDebugMessageLength;
1430 break;
1431 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1432 *params = mExtensions.maxDebugLoggedMessages;
1433 break;
1434 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1435 *params = mExtensions.maxDebugGroupStackDepth;
1436 break;
1437 case GL_MAX_LABEL_LENGTH:
1438 *params = mExtensions.maxLabelLength;
1439 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001440
Martin Radeve5285d22017-07-14 16:23:53 +03001441 // GL_ANGLE_multiview
1442 case GL_MAX_VIEWS_ANGLE:
1443 *params = mExtensions.maxViews;
1444 break;
1445
Jamie Madill231c7f52017-04-26 13:45:37 -04001446 // GL_EXT_disjoint_timer_query
1447 case GL_GPU_DISJOINT_EXT:
1448 *params = mImplementation->getGPUDisjoint();
1449 break;
1450 case GL_MAX_FRAMEBUFFER_WIDTH:
1451 *params = mCaps.maxFramebufferWidth;
1452 break;
1453 case GL_MAX_FRAMEBUFFER_HEIGHT:
1454 *params = mCaps.maxFramebufferHeight;
1455 break;
1456 case GL_MAX_FRAMEBUFFER_SAMPLES:
1457 *params = mCaps.maxFramebufferSamples;
1458 break;
1459 case GL_MAX_SAMPLE_MASK_WORDS:
1460 *params = mCaps.maxSampleMaskWords;
1461 break;
1462 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1463 *params = mCaps.maxColorTextureSamples;
1464 break;
1465 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1466 *params = mCaps.maxDepthTextureSamples;
1467 break;
1468 case GL_MAX_INTEGER_SAMPLES:
1469 *params = mCaps.maxIntegerSamples;
1470 break;
1471 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1472 *params = mCaps.maxVertexAttribRelativeOffset;
1473 break;
1474 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1475 *params = mCaps.maxVertexAttribBindings;
1476 break;
1477 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1478 *params = mCaps.maxVertexAttribStride;
1479 break;
1480 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1481 *params = mCaps.maxVertexAtomicCounterBuffers;
1482 break;
1483 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1484 *params = mCaps.maxVertexAtomicCounters;
1485 break;
1486 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1487 *params = mCaps.maxVertexImageUniforms;
1488 break;
1489 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1490 *params = mCaps.maxVertexShaderStorageBlocks;
1491 break;
1492 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1493 *params = mCaps.maxFragmentAtomicCounterBuffers;
1494 break;
1495 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1496 *params = mCaps.maxFragmentAtomicCounters;
1497 break;
1498 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1499 *params = mCaps.maxFragmentImageUniforms;
1500 break;
1501 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1502 *params = mCaps.maxFragmentShaderStorageBlocks;
1503 break;
1504 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1505 *params = mCaps.minProgramTextureGatherOffset;
1506 break;
1507 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1508 *params = mCaps.maxProgramTextureGatherOffset;
1509 break;
1510 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1511 *params = mCaps.maxComputeWorkGroupInvocations;
1512 break;
1513 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1514 *params = mCaps.maxComputeUniformBlocks;
1515 break;
1516 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1517 *params = mCaps.maxComputeTextureImageUnits;
1518 break;
1519 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1520 *params = mCaps.maxComputeSharedMemorySize;
1521 break;
1522 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1523 *params = mCaps.maxComputeUniformComponents;
1524 break;
1525 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1526 *params = mCaps.maxComputeAtomicCounterBuffers;
1527 break;
1528 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1529 *params = mCaps.maxComputeAtomicCounters;
1530 break;
1531 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1532 *params = mCaps.maxComputeImageUniforms;
1533 break;
1534 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1535 *params = mCaps.maxCombinedComputeUniformComponents;
1536 break;
1537 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1538 *params = mCaps.maxComputeShaderStorageBlocks;
1539 break;
1540 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1541 *params = mCaps.maxCombinedShaderOutputResources;
1542 break;
1543 case GL_MAX_UNIFORM_LOCATIONS:
1544 *params = mCaps.maxUniformLocations;
1545 break;
1546 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1547 *params = mCaps.maxAtomicCounterBufferBindings;
1548 break;
1549 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1550 *params = mCaps.maxAtomicCounterBufferSize;
1551 break;
1552 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1553 *params = mCaps.maxCombinedAtomicCounterBuffers;
1554 break;
1555 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1556 *params = mCaps.maxCombinedAtomicCounters;
1557 break;
1558 case GL_MAX_IMAGE_UNITS:
1559 *params = mCaps.maxImageUnits;
1560 break;
1561 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1562 *params = mCaps.maxCombinedImageUniforms;
1563 break;
1564 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1565 *params = mCaps.maxShaderStorageBufferBindings;
1566 break;
1567 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1568 *params = mCaps.maxCombinedShaderStorageBlocks;
1569 break;
1570 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1571 *params = mCaps.shaderStorageBufferOffsetAlignment;
1572 break;
1573 default:
1574 mGLState.getIntegerv(this, pname, params);
1575 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001576 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001577}
1578
Jamie Madill7f0c5a42017-08-26 22:43:26 -04001579void Context::getInteger64vImpl(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001580{
Shannon Woods53a94a82014-06-24 15:20:36 -04001581 // Queries about context capabilities and maximums are answered by Context.
1582 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001583 switch (pname)
1584 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001585 case GL_MAX_ELEMENT_INDEX:
1586 *params = mCaps.maxElementIndex;
1587 break;
1588 case GL_MAX_UNIFORM_BLOCK_SIZE:
1589 *params = mCaps.maxUniformBlockSize;
1590 break;
1591 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1592 *params = mCaps.maxCombinedVertexUniformComponents;
1593 break;
1594 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1595 *params = mCaps.maxCombinedFragmentUniformComponents;
1596 break;
1597 case GL_MAX_SERVER_WAIT_TIMEOUT:
1598 *params = mCaps.maxServerWaitTimeout;
1599 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001600
Jamie Madill231c7f52017-04-26 13:45:37 -04001601 // GL_EXT_disjoint_timer_query
1602 case GL_TIMESTAMP_EXT:
1603 *params = mImplementation->getTimestamp();
1604 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001605
Jamie Madill231c7f52017-04-26 13:45:37 -04001606 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1607 *params = mCaps.maxShaderStorageBlockSize;
1608 break;
1609 default:
1610 UNREACHABLE();
1611 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001612 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001613}
1614
Geoff Lang70d0f492015-12-10 17:45:46 -05001615void Context::getPointerv(GLenum pname, void **params) const
1616{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001617 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001618}
1619
Martin Radev66fb8202016-07-28 11:45:20 +03001620void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001621{
Shannon Woods53a94a82014-06-24 15:20:36 -04001622 // Queries about context capabilities and maximums are answered by Context.
1623 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001624
1625 GLenum nativeType;
1626 unsigned int numParams;
1627 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1628 ASSERT(queryStatus);
1629
1630 if (nativeType == GL_INT)
1631 {
1632 switch (target)
1633 {
1634 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1635 ASSERT(index < 3u);
1636 *data = mCaps.maxComputeWorkGroupCount[index];
1637 break;
1638 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1639 ASSERT(index < 3u);
1640 *data = mCaps.maxComputeWorkGroupSize[index];
1641 break;
1642 default:
1643 mGLState.getIntegeri_v(target, index, data);
1644 }
1645 }
1646 else
1647 {
1648 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1649 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001650}
1651
Martin Radev66fb8202016-07-28 11:45:20 +03001652void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001653{
Shannon Woods53a94a82014-06-24 15:20:36 -04001654 // Queries about context capabilities and maximums are answered by Context.
1655 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001656
1657 GLenum nativeType;
1658 unsigned int numParams;
1659 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1660 ASSERT(queryStatus);
1661
1662 if (nativeType == GL_INT_64_ANGLEX)
1663 {
1664 mGLState.getInteger64i_v(target, index, data);
1665 }
1666 else
1667 {
1668 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1669 }
1670}
1671
1672void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1673{
1674 // Queries about context capabilities and maximums are answered by Context.
1675 // Queries about current GL state values are answered by State.
1676
1677 GLenum nativeType;
1678 unsigned int numParams;
1679 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1680 ASSERT(queryStatus);
1681
1682 if (nativeType == GL_BOOL)
1683 {
1684 mGLState.getBooleani_v(target, index, data);
1685 }
1686 else
1687 {
1688 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1689 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001690}
1691
He Yunchao010e4db2017-03-03 14:22:06 +08001692void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1693{
1694 Buffer *buffer = mGLState.getTargetBuffer(target);
1695 QueryBufferParameteriv(buffer, pname, params);
1696}
1697
1698void Context::getFramebufferAttachmentParameteriv(GLenum target,
1699 GLenum attachment,
1700 GLenum pname,
1701 GLint *params)
1702{
1703 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1704 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1705}
1706
1707void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1708{
1709 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1710 QueryRenderbufferiv(this, renderbuffer, pname, params);
1711}
1712
1713void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1714{
1715 Texture *texture = getTargetTexture(target);
1716 QueryTexParameterfv(texture, pname, params);
1717}
1718
1719void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1720{
1721 Texture *texture = getTargetTexture(target);
1722 QueryTexParameteriv(texture, pname, params);
1723}
1724void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1725{
1726 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001727 SetTexParameterf(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001728}
1729
1730void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1731{
1732 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001733 SetTexParameterfv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001734}
1735
1736void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1737{
1738 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001739 SetTexParameteri(this, texture, pname, param);
He Yunchao010e4db2017-03-03 14:22:06 +08001740}
1741
1742void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1743{
1744 Texture *texture = getTargetTexture(target);
Jamie Madill4928b7c2017-06-20 12:57:39 -04001745 SetTexParameteriv(this, texture, pname, params);
He Yunchao010e4db2017-03-03 14:22:06 +08001746}
1747
Jamie Madill675fe712016-12-19 13:07:54 -05001748void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001749{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001750 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001751 ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
1752 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001753}
1754
Jamie Madill675fe712016-12-19 13:07:54 -05001755void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001756{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001757 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001758 ANGLE_CONTEXT_TRY(
1759 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
1760 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001761}
1762
Jamie Madill876429b2017-04-20 15:46:24 -04001763void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001764{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001765 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001766 ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
Geoff Langf6db0982015-08-25 13:04:00 -04001767}
1768
Jamie Madill675fe712016-12-19 13:07:54 -05001769void Context::drawElementsInstanced(GLenum mode,
1770 GLsizei count,
1771 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001772 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001773 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001774{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001775 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001776 ANGLE_CONTEXT_TRY(
Qin Jiajia1da00652017-06-20 17:16:25 +08001777 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
Geoff Langf6db0982015-08-25 13:04:00 -04001778}
1779
Jamie Madill675fe712016-12-19 13:07:54 -05001780void Context::drawRangeElements(GLenum mode,
1781 GLuint start,
1782 GLuint end,
1783 GLsizei count,
1784 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001785 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001786{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001787 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001788 ANGLE_CONTEXT_TRY(
1789 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001790}
1791
Jamie Madill876429b2017-04-20 15:46:24 -04001792void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001793{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001794 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001795 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001796}
1797
Jamie Madill876429b2017-04-20 15:46:24 -04001798void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001799{
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001800 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
Jamie Madillb6664922017-07-25 12:55:04 -04001801 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
Jiajia Qind9671222016-11-29 16:30:31 +08001802}
1803
Jamie Madill675fe712016-12-19 13:07:54 -05001804void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001805{
Jamie Madill675fe712016-12-19 13:07:54 -05001806 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001807}
1808
Jamie Madill675fe712016-12-19 13:07:54 -05001809void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001810{
Jamie Madill675fe712016-12-19 13:07:54 -05001811 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001812}
1813
Austin Kinross6ee1e782015-05-29 17:05:37 -07001814void Context::insertEventMarker(GLsizei length, const char *marker)
1815{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001816 ASSERT(mImplementation);
1817 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001818}
1819
1820void Context::pushGroupMarker(GLsizei length, const char *marker)
1821{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001822 ASSERT(mImplementation);
1823 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001824}
1825
1826void Context::popGroupMarker()
1827{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001828 ASSERT(mImplementation);
1829 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001830}
1831
Geoff Langd8605522016-04-13 10:19:12 -04001832void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1833{
1834 Program *programObject = getProgram(program);
1835 ASSERT(programObject);
1836
1837 programObject->bindUniformLocation(location, name);
1838}
1839
Sami Väisänena797e062016-05-12 15:23:40 +03001840void Context::setCoverageModulation(GLenum components)
1841{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001842 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001843}
1844
Sami Väisänene45e53b2016-05-25 10:36:04 +03001845void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1846{
1847 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1848}
1849
1850void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1851{
1852 GLfloat I[16];
1853 angle::Matrix<GLfloat>::setToIdentity(I);
1854
1855 mGLState.loadPathRenderingMatrix(matrixMode, I);
1856}
1857
1858void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1859{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001860 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001861 if (!pathObj)
1862 return;
1863
1864 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1865 syncRendererState();
1866
1867 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1868}
1869
1870void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1871{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001872 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001873 if (!pathObj)
1874 return;
1875
1876 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1877 syncRendererState();
1878
1879 mImplementation->stencilStrokePath(pathObj, reference, mask);
1880}
1881
1882void Context::coverFillPath(GLuint path, GLenum coverMode)
1883{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001884 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001885 if (!pathObj)
1886 return;
1887
1888 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1889 syncRendererState();
1890
1891 mImplementation->coverFillPath(pathObj, coverMode);
1892}
1893
1894void Context::coverStrokePath(GLuint path, GLenum coverMode)
1895{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001896 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001897 if (!pathObj)
1898 return;
1899
1900 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1901 syncRendererState();
1902
1903 mImplementation->coverStrokePath(pathObj, coverMode);
1904}
1905
1906void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1907{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001908 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001909 if (!pathObj)
1910 return;
1911
1912 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1913 syncRendererState();
1914
1915 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1916}
1917
1918void Context::stencilThenCoverStrokePath(GLuint path,
1919 GLint reference,
1920 GLuint mask,
1921 GLenum coverMode)
1922{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001923 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001924 if (!pathObj)
1925 return;
1926
1927 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1928 syncRendererState();
1929
1930 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1931}
1932
Sami Väisänend59ca052016-06-21 16:10:00 +03001933void Context::coverFillPathInstanced(GLsizei numPaths,
1934 GLenum pathNameType,
1935 const void *paths,
1936 GLuint pathBase,
1937 GLenum coverMode,
1938 GLenum transformType,
1939 const GLfloat *transformValues)
1940{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001941 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001942
1943 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1944 syncRendererState();
1945
1946 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1947}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001948
Sami Väisänend59ca052016-06-21 16:10:00 +03001949void Context::coverStrokePathInstanced(GLsizei numPaths,
1950 GLenum pathNameType,
1951 const void *paths,
1952 GLuint pathBase,
1953 GLenum coverMode,
1954 GLenum transformType,
1955 const GLfloat *transformValues)
1956{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001957 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001958
1959 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1960 syncRendererState();
1961
1962 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1963 transformValues);
1964}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001965
Sami Väisänend59ca052016-06-21 16:10:00 +03001966void Context::stencilFillPathInstanced(GLsizei numPaths,
1967 GLenum pathNameType,
1968 const void *paths,
1969 GLuint pathBase,
1970 GLenum fillMode,
1971 GLuint mask,
1972 GLenum transformType,
1973 const GLfloat *transformValues)
1974{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001975 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001976
1977 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1978 syncRendererState();
1979
1980 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1981 transformValues);
1982}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001983
Sami Väisänend59ca052016-06-21 16:10:00 +03001984void Context::stencilStrokePathInstanced(GLsizei numPaths,
1985 GLenum pathNameType,
1986 const void *paths,
1987 GLuint pathBase,
1988 GLint reference,
1989 GLuint mask,
1990 GLenum transformType,
1991 const GLfloat *transformValues)
1992{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001993 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001994
1995 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1996 syncRendererState();
1997
1998 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1999 transformValues);
2000}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002001
Sami Väisänend59ca052016-06-21 16:10:00 +03002002void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2003 GLenum pathNameType,
2004 const void *paths,
2005 GLuint pathBase,
2006 GLenum fillMode,
2007 GLuint mask,
2008 GLenum coverMode,
2009 GLenum transformType,
2010 const GLfloat *transformValues)
2011{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002012 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002013
2014 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2015 syncRendererState();
2016
2017 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2018 transformType, transformValues);
2019}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002020
Sami Väisänend59ca052016-06-21 16:10:00 +03002021void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2022 GLenum pathNameType,
2023 const void *paths,
2024 GLuint pathBase,
2025 GLint reference,
2026 GLuint mask,
2027 GLenum coverMode,
2028 GLenum transformType,
2029 const GLfloat *transformValues)
2030{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002031 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002032
2033 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2034 syncRendererState();
2035
2036 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2037 transformType, transformValues);
2038}
2039
Sami Väisänen46eaa942016-06-29 10:26:37 +03002040void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2041{
2042 auto *programObject = getProgram(program);
2043
2044 programObject->bindFragmentInputLocation(location, name);
2045}
2046
2047void Context::programPathFragmentInputGen(GLuint program,
2048 GLint location,
2049 GLenum genMode,
2050 GLint components,
2051 const GLfloat *coeffs)
2052{
2053 auto *programObject = getProgram(program);
2054
Jamie Madillbd044ed2017-06-05 12:59:21 -04002055 programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
Sami Väisänen46eaa942016-06-29 10:26:37 +03002056}
2057
jchen1015015f72017-03-16 13:54:21 +08002058GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2059{
jchen10fd7c3b52017-03-21 15:36:03 +08002060 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002061 return QueryProgramResourceIndex(programObject, programInterface, name);
2062}
2063
jchen10fd7c3b52017-03-21 15:36:03 +08002064void Context::getProgramResourceName(GLuint program,
2065 GLenum programInterface,
2066 GLuint index,
2067 GLsizei bufSize,
2068 GLsizei *length,
2069 GLchar *name)
2070{
2071 const auto *programObject = getProgram(program);
2072 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2073}
2074
jchen10191381f2017-04-11 13:59:04 +08002075GLint Context::getProgramResourceLocation(GLuint program,
2076 GLenum programInterface,
2077 const GLchar *name)
2078{
2079 const auto *programObject = getProgram(program);
2080 return QueryProgramResourceLocation(programObject, programInterface, name);
2081}
2082
jchen10880683b2017-04-12 16:21:55 +08002083void Context::getProgramResourceiv(GLuint program,
2084 GLenum programInterface,
2085 GLuint index,
2086 GLsizei propCount,
2087 const GLenum *props,
2088 GLsizei bufSize,
2089 GLsizei *length,
2090 GLint *params)
2091{
2092 const auto *programObject = getProgram(program);
2093 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2094 length, params);
2095}
2096
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002097Error Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002098{
Geoff Langda5777c2014-07-11 09:52:58 -04002099 if (error.isError())
2100 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002101 GLenum code = error.getCode();
2102 mErrors.insert(code);
2103 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2104 {
2105 markContextLost();
2106 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002107
2108 if (!error.getMessage().empty())
2109 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002110 auto *debug = &mGLState.getDebug();
2111 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2112 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002113 }
Geoff Langda5777c2014-07-11 09:52:58 -04002114 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002115
2116 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002117}
2118
2119// Get one of the recorded errors and clear its flag, if any.
2120// [OpenGL ES 2.0.24] section 2.5 page 13.
2121GLenum Context::getError()
2122{
Geoff Langda5777c2014-07-11 09:52:58 -04002123 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002124 {
Geoff Langda5777c2014-07-11 09:52:58 -04002125 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002126 }
Geoff Langda5777c2014-07-11 09:52:58 -04002127 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002128 {
Geoff Langda5777c2014-07-11 09:52:58 -04002129 GLenum error = *mErrors.begin();
2130 mErrors.erase(mErrors.begin());
2131 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002132 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002133}
2134
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002135// NOTE: this function should not assume that this context is current!
2136void Context::markContextLost()
2137{
2138 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002139 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002140 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002141 mContextLostForced = true;
2142 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002143 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002144}
2145
2146bool Context::isContextLost()
2147{
2148 return mContextLost;
2149}
2150
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002151GLenum Context::getResetStatus()
2152{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002153 // Even if the application doesn't want to know about resets, we want to know
2154 // as it will allow us to skip all the calls.
2155 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002156 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002157 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002158 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002159 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002160 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002161
2162 // EXT_robustness, section 2.6: If the reset notification behavior is
2163 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2164 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2165 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002166 }
2167
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002168 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2169 // status should be returned at least once, and GL_NO_ERROR should be returned
2170 // once the device has finished resetting.
2171 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002172 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002173 ASSERT(mResetStatus == GL_NO_ERROR);
2174 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002175
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002176 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002177 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002178 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002179 }
2180 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002181 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002182 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002183 // If markContextLost was used to mark the context lost then
2184 // assume that is not recoverable, and continue to report the
2185 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002186 mResetStatus = mImplementation->getResetStatus();
2187 }
Jamie Madill893ab082014-05-16 16:56:10 -04002188
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002189 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002190}
2191
2192bool Context::isResetNotificationEnabled()
2193{
2194 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2195}
2196
Corentin Walleze3b10e82015-05-20 11:06:25 -04002197const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002198{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002199 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002200}
2201
2202EGLenum Context::getClientType() const
2203{
2204 return mClientType;
2205}
2206
2207EGLenum Context::getRenderBuffer() const
2208{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002209 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2210 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002211 {
2212 return EGL_NONE;
2213 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002214
2215 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2216 ASSERT(backAttachment != nullptr);
2217 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002218}
2219
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002220VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002221{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002222 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002223 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2224 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002225 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002226 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2227 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002228
Jamie Madill96a483b2017-06-27 16:49:21 -04002229 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002230 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002231
2232 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002233}
2234
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002235TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002236{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002237 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002238 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2239 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002240 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002241 transformFeedback =
2242 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002243 transformFeedback->addRef();
Jamie Madill96a483b2017-06-27 16:49:21 -04002244 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002245 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002246
2247 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002248}
2249
2250bool Context::isVertexArrayGenerated(GLuint vertexArray)
2251{
Jamie Madill96a483b2017-06-27 16:49:21 -04002252 ASSERT(mVertexArrayMap.contains(0));
2253 return mVertexArrayMap.contains(vertexArray);
Geoff Lang36167ab2015-12-07 10:27:14 -05002254}
2255
2256bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2257{
Jamie Madill96a483b2017-06-27 16:49:21 -04002258 ASSERT(mTransformFeedbackMap.contains(0));
2259 return mTransformFeedbackMap.contains(transformFeedback);
Geoff Lang36167ab2015-12-07 10:27:14 -05002260}
2261
Shannon Woods53a94a82014-06-24 15:20:36 -04002262void Context::detachTexture(GLuint texture)
2263{
2264 // Simple pass-through to State's detachTexture method, as textures do not require
2265 // allocation map management either here or in the resource manager at detach time.
2266 // Zero textures are held by the Context, and we don't attempt to request them from
2267 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002268 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002269}
2270
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002271void Context::detachBuffer(GLuint buffer)
2272{
Yuly Novikov5807a532015-12-03 13:01:22 -05002273 // Simple pass-through to State's detachBuffer method, since
2274 // only buffer attachments to container objects that are bound to the current context
2275 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002276
Yuly Novikov5807a532015-12-03 13:01:22 -05002277 // [OpenGL ES 3.2] section 5.1.2 page 45:
2278 // Attachments to unbound container objects, such as
2279 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2280 // are not affected and continue to act as references on the deleted object
Jamie Madill4928b7c2017-06-20 12:57:39 -04002281 mGLState.detachBuffer(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002282}
2283
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002284void Context::detachFramebuffer(GLuint framebuffer)
2285{
Shannon Woods53a94a82014-06-24 15:20:36 -04002286 // Framebuffer detachment is handled by Context, because 0 is a valid
2287 // Framebuffer object, and a pointer to it must be passed from Context
2288 // to State at binding time.
2289
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002290 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002291 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2292 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2293 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002294
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002295 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002296 {
2297 bindReadFramebuffer(0);
2298 }
2299
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002300 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002301 {
2302 bindDrawFramebuffer(0);
2303 }
2304}
2305
2306void Context::detachRenderbuffer(GLuint renderbuffer)
2307{
Jamie Madilla02315b2017-02-23 14:14:47 -05002308 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002309}
2310
Jamie Madill57a89722013-07-02 11:57:03 -04002311void Context::detachVertexArray(GLuint vertexArray)
2312{
Jamie Madill77a72f62015-04-14 11:18:32 -04002313 // Vertex array detachment is handled by Context, because 0 is a valid
2314 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002315 // binding time.
2316
Jamie Madill57a89722013-07-02 11:57:03 -04002317 // [OpenGL ES 3.0.2] section 2.10 page 43:
2318 // If a vertex array object that is currently bound is deleted, the binding
2319 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002320 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002321 {
2322 bindVertexArray(0);
2323 }
2324}
2325
Geoff Langc8058452014-02-03 12:04:11 -05002326void Context::detachTransformFeedback(GLuint transformFeedback)
2327{
Corentin Walleza2257da2016-04-19 16:43:12 -04002328 // Transform feedback detachment is handled by Context, because 0 is a valid
2329 // transform feedback, and a pointer to it must be passed from Context to State at
2330 // binding time.
2331
2332 // The OpenGL specification doesn't mention what should happen when the currently bound
2333 // transform feedback object is deleted. Since it is a container object, we treat it like
2334 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madill4928b7c2017-06-20 12:57:39 -04002335 if (mGLState.removeTransformFeedbackBinding(this, transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002336 {
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04002337 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
Corentin Walleza2257da2016-04-19 16:43:12 -04002338 }
Geoff Langc8058452014-02-03 12:04:11 -05002339}
2340
Jamie Madilldc356042013-07-19 16:36:57 -04002341void Context::detachSampler(GLuint sampler)
2342{
Jamie Madill4928b7c2017-06-20 12:57:39 -04002343 mGLState.detachSampler(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002344}
2345
Jamie Madill3ef140a2017-08-26 23:11:21 -04002346void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002347{
Shaodde78e82017-05-22 14:13:27 +08002348 mGLState.setVertexAttribDivisor(this, index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002349}
2350
Jamie Madille29d1672013-07-19 16:36:57 -04002351void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2352{
Geoff Langc1984ed2016-10-07 12:41:00 -04002353 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002354 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002355 SetSamplerParameteri(samplerObject, pname, param);
2356}
Jamie Madille29d1672013-07-19 16:36:57 -04002357
Geoff Langc1984ed2016-10-07 12:41:00 -04002358void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2359{
2360 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002361 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002362 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002363}
2364
2365void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2366{
Geoff Langc1984ed2016-10-07 12:41:00 -04002367 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002368 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002369 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002370}
2371
Geoff Langc1984ed2016-10-07 12:41:00 -04002372void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002373{
Geoff Langc1984ed2016-10-07 12:41:00 -04002374 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002375 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002376 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002377}
2378
Geoff Langc1984ed2016-10-07 12:41:00 -04002379void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002380{
Geoff Langc1984ed2016-10-07 12:41:00 -04002381 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002382 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002383 QuerySamplerParameteriv(samplerObject, pname, params);
2384}
Jamie Madill9675b802013-07-19 16:36:59 -04002385
Geoff Langc1984ed2016-10-07 12:41:00 -04002386void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2387{
2388 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002389 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002390 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002391}
2392
Olli Etuahof0fee072016-03-30 15:11:58 +03002393void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2394{
2395 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002396 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002397}
2398
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002399void Context::initRendererString()
2400{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002401 std::ostringstream rendererString;
2402 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002403 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002404 rendererString << ")";
2405
Geoff Langcec35902014-04-16 10:52:36 -04002406 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002407}
2408
Geoff Langc339c4e2016-11-29 10:37:36 -05002409void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002410{
Geoff Langc339c4e2016-11-29 10:37:36 -05002411 const Version &clientVersion = getClientVersion();
2412
2413 std::ostringstream versionString;
2414 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2415 << ANGLE_VERSION_STRING << ")";
2416 mVersionString = MakeStaticString(versionString.str());
2417
2418 std::ostringstream shadingLanguageVersionString;
2419 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2420 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2421 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2422 << ")";
2423 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002424}
2425
Geoff Langcec35902014-04-16 10:52:36 -04002426void Context::initExtensionStrings()
2427{
Geoff Langc339c4e2016-11-29 10:37:36 -05002428 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2429 std::ostringstream combinedStringStream;
2430 std::copy(strings.begin(), strings.end(),
2431 std::ostream_iterator<const char *>(combinedStringStream, " "));
2432 return MakeStaticString(combinedStringStream.str());
2433 };
2434
2435 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002436 for (const auto &extensionString : mExtensions.getStrings())
2437 {
2438 mExtensionStrings.push_back(MakeStaticString(extensionString));
2439 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002440 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002441
Bryan Bernhart58806562017-01-05 13:09:31 -08002442 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2443
Geoff Langc339c4e2016-11-29 10:37:36 -05002444 mRequestableExtensionStrings.clear();
2445 for (const auto &extensionInfo : GetExtensionInfoMap())
2446 {
2447 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002448 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2449 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002450 {
2451 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2452 }
2453 }
2454 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002455}
2456
Geoff Langc339c4e2016-11-29 10:37:36 -05002457const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002458{
Geoff Langc339c4e2016-11-29 10:37:36 -05002459 switch (name)
2460 {
2461 case GL_VENDOR:
2462 return reinterpret_cast<const GLubyte *>("Google Inc.");
2463
2464 case GL_RENDERER:
2465 return reinterpret_cast<const GLubyte *>(mRendererString);
2466
2467 case GL_VERSION:
2468 return reinterpret_cast<const GLubyte *>(mVersionString);
2469
2470 case GL_SHADING_LANGUAGE_VERSION:
2471 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2472
2473 case GL_EXTENSIONS:
2474 return reinterpret_cast<const GLubyte *>(mExtensionString);
2475
2476 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2477 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2478
2479 default:
2480 UNREACHABLE();
2481 return nullptr;
2482 }
Geoff Langcec35902014-04-16 10:52:36 -04002483}
2484
Geoff Langc339c4e2016-11-29 10:37:36 -05002485const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002486{
Geoff Langc339c4e2016-11-29 10:37:36 -05002487 switch (name)
2488 {
2489 case GL_EXTENSIONS:
2490 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2491
2492 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2493 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2494
2495 default:
2496 UNREACHABLE();
2497 return nullptr;
2498 }
Geoff Langcec35902014-04-16 10:52:36 -04002499}
2500
2501size_t Context::getExtensionStringCount() const
2502{
2503 return mExtensionStrings.size();
2504}
2505
Geoff Langc339c4e2016-11-29 10:37:36 -05002506void Context::requestExtension(const char *name)
2507{
2508 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2509 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2510 const auto &extension = extensionInfos.at(name);
2511 ASSERT(extension.Requestable);
2512
2513 if (mExtensions.*(extension.ExtensionsMember))
2514 {
2515 // Extension already enabled
2516 return;
2517 }
2518
2519 mExtensions.*(extension.ExtensionsMember) = true;
2520 updateCaps();
2521 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002522
Jamie Madill2f348d22017-06-05 10:50:59 -04002523 // Release the shader compiler so it will be re-created with the requested extensions enabled.
2524 releaseShaderCompiler();
Geoff Lang9aded172017-04-05 11:07:56 -04002525
2526 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2527 // formats renderable or sampleable.
2528 mState.mTextures->invalidateTextureComplenessCache();
2529 for (auto &zeroTexture : mZeroTextures)
2530 {
2531 zeroTexture.second->invalidateCompletenessCache();
2532 }
2533
2534 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002535}
2536
2537size_t Context::getRequestableExtensionStringCount() const
2538{
2539 return mRequestableExtensionStrings.size();
2540}
2541
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002542void Context::beginTransformFeedback(GLenum primitiveMode)
2543{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002544 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002545 ASSERT(transformFeedback != nullptr);
2546 ASSERT(!transformFeedback->isPaused());
2547
Jamie Madill6c1f6712017-02-14 19:08:04 -05002548 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002549}
2550
2551bool Context::hasActiveTransformFeedback(GLuint program) const
2552{
2553 for (auto pair : mTransformFeedbackMap)
2554 {
2555 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2556 {
2557 return true;
2558 }
2559 }
2560 return false;
2561}
2562
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002563void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002564{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002565 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002566
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002567 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002568
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002569 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002570
Geoff Langeb66a6e2016-10-31 13:06:12 -04002571 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002572 {
2573 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002574 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002575 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002576 mExtensions.textureNorm16 = false;
Martin Radev137032d2017-07-13 10:11:12 +03002577 mExtensions.multiview = false;
2578 mExtensions.maxViews = 1u;
Geoff Lang493daf52014-07-03 13:38:44 -04002579 }
2580
Geoff Langeb66a6e2016-10-31 13:06:12 -04002581 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002582 {
2583 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002584 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002585 }
2586
Jamie Madill00ed7a12016-05-19 13:13:38 -04002587 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002588 mExtensions.bindUniformLocation = true;
2589 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002590 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002591 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002592 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002593
2594 // Enable the no error extension if the context was created with the flag.
2595 mExtensions.noError = mSkipValidation;
2596
Corentin Wallezccab69d2017-01-27 16:57:15 -05002597 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002598 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002599
Geoff Lang70d0f492015-12-10 17:45:46 -05002600 // Explicitly enable GL_KHR_debug
2601 mExtensions.debug = true;
2602 mExtensions.maxDebugMessageLength = 1024;
2603 mExtensions.maxDebugLoggedMessages = 1024;
2604 mExtensions.maxDebugGroupStackDepth = 1024;
2605 mExtensions.maxLabelLength = 1024;
2606
Geoff Langff5b2d52016-09-07 11:32:23 -04002607 // Explicitly enable GL_ANGLE_robust_client_memory
2608 mExtensions.robustClientMemory = true;
2609
Jamie Madille08a1d32017-03-07 17:24:06 -05002610 // Determine robust resource init availability from EGL.
2611 mExtensions.robustResourceInitialization =
Jamie Madill948bbe52017-06-01 13:10:42 -04002612 egl::Display::GetClientExtensions().displayRobustResourceInitialization;
Jamie Madille08a1d32017-03-07 17:24:06 -05002613
Jamie Madillc43be722017-07-13 16:22:14 -04002614 // Enable the cache control query unconditionally.
2615 mExtensions.programCacheControl = true;
2616
Geoff Lang301d1612014-07-09 10:34:37 -04002617 // Apply implementation limits
2618 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002619 mCaps.maxVertexAttribBindings =
2620 getClientVersion() < ES_3_1
2621 ? mCaps.maxVertexAttributes
2622 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2623
Jamie Madill231c7f52017-04-26 13:45:37 -04002624 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2625 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2626 mCaps.maxVertexOutputComponents =
2627 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002628
Jamie Madill231c7f52017-04-26 13:45:37 -04002629 mCaps.maxFragmentInputComponents =
2630 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002631
Geoff Langc287ea62016-09-16 14:46:51 -04002632 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002633 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002634 for (const auto &extensionInfo : GetExtensionInfoMap())
2635 {
2636 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002637 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002638 {
2639 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2640 }
2641 }
2642
2643 // Generate texture caps
2644 updateCaps();
2645}
2646
2647void Context::updateCaps()
2648{
Geoff Lang900013c2014-07-07 11:32:19 -04002649 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002650 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002651
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002652 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002653 {
Geoff Langca271392017-04-05 12:30:00 -04002654 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002655 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002656
Geoff Langca271392017-04-05 12:30:00 -04002657 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002658
Geoff Lang0d8b7242015-09-09 14:56:53 -04002659 // Update the format caps based on the client version and extensions.
2660 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2661 // ES3.
2662 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002663 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002664 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002665 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002666 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002667 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002668
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002669 // OpenGL ES does not support multisampling with non-rendererable formats
2670 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
Olli Etuaho50c562d2017-06-06 14:43:30 +03002671 if (!formatCaps.renderable ||
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002672 (getClientVersion() < ES_3_1 &&
2673 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002674 {
Geoff Langd87878e2014-09-19 15:42:59 -04002675 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002676 }
Olli Etuaho50c562d2017-06-06 14:43:30 +03002677 else
2678 {
2679 // We may have limited the max samples for some required renderbuffer formats due to
2680 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
2681 GLuint formatMaxSamples = formatCaps.getMaxSamples();
2682
2683 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
2684 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
2685 // exception of signed and unsigned integer formats."
2686 if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT &&
2687 formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
2688 {
2689 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
2690 mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples);
2691 }
2692
2693 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
2694 if (getClientVersion() >= ES_3_1)
2695 {
2696 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
2697 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
2698 // the exception that the signed and unsigned integer formats are required only to
2699 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
2700 // multisamples, which must be at least one."
2701 if (formatInfo.componentType == GL_INT ||
2702 formatInfo.componentType == GL_UNSIGNED_INT)
2703 {
2704 mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples);
2705 }
2706
2707 // GLES 3.1 section 19.3.1.
2708 if (formatCaps.texturable)
2709 {
2710 if (formatInfo.depthBits > 0)
2711 {
2712 mCaps.maxDepthTextureSamples =
2713 std::min(mCaps.maxDepthTextureSamples, formatMaxSamples);
2714 }
2715 else if (formatInfo.redBits > 0)
2716 {
2717 mCaps.maxColorTextureSamples =
2718 std::min(mCaps.maxColorTextureSamples, formatMaxSamples);
2719 }
2720 }
2721 }
2722 }
Geoff Langd87878e2014-09-19 15:42:59 -04002723
2724 if (formatCaps.texturable && formatInfo.compressed)
2725 {
Geoff Langca271392017-04-05 12:30:00 -04002726 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002727 }
2728
Geoff Langca271392017-04-05 12:30:00 -04002729 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002730 }
Jamie Madill32447362017-06-28 14:53:52 -04002731
2732 // If program binary is disabled, blank out the memory cache pointer.
2733 if (!mImplementation->getNativeExtensions().getProgramBinary)
2734 {
2735 mMemoryProgramCache = nullptr;
2736 }
Geoff Lang493daf52014-07-03 13:38:44 -04002737}
2738
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002739void Context::initWorkarounds()
2740{
Jamie Madill761b02c2017-06-23 16:27:06 -04002741 // Apply back-end workarounds.
2742 mImplementation->applyNativeWorkarounds(&mWorkarounds);
2743
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002744 // Lose the context upon out of memory error if the application is
2745 // expecting to watch for those events.
2746 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2747}
2748
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002749Error Context::prepareForDraw(GLenum drawMode)
Jamie Madillb6664922017-07-25 12:55:04 -04002750{
2751 syncRendererState();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002752
2753 InfoLog infoLog;
2754 Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
2755 mMemoryProgramCache, drawMode);
Jamie Madilla836b462017-08-16 14:58:35 -04002756 if (err.isError() || infoLog.getLength() > 0)
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002757 {
2758 WARN() << "Dynamic recompilation error log: " << infoLog.str();
2759 }
2760 return err;
Jamie Madillb6664922017-07-25 12:55:04 -04002761}
2762
Jamie Madill1b94d432015-08-07 13:23:23 -04002763void Context::syncRendererState()
2764{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002765 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Jamie Madillfe548342017-06-19 11:13:24 -04002766 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002767 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002768 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002769}
2770
Jamie Madillad9f24e2016-02-12 09:27:24 -05002771void Context::syncRendererState(const State::DirtyBits &bitMask,
2772 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002773{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002774 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Jamie Madillfe548342017-06-19 11:13:24 -04002775 mImplementation->syncState(this, dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002776 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002777 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002778}
Jamie Madillc29968b2016-01-20 11:17:23 -05002779
2780void Context::blitFramebuffer(GLint srcX0,
2781 GLint srcY0,
2782 GLint srcX1,
2783 GLint srcY1,
2784 GLint dstX0,
2785 GLint dstY0,
2786 GLint dstX1,
2787 GLint dstY1,
2788 GLbitfield mask,
2789 GLenum filter)
2790{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002791 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002792 ASSERT(drawFramebuffer);
2793
2794 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2795 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2796
Jamie Madillad9f24e2016-02-12 09:27:24 -05002797 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002798
Jamie Madillc564c072017-06-01 12:45:42 -04002799 handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002800}
Jamie Madillc29968b2016-01-20 11:17:23 -05002801
2802void Context::clear(GLbitfield mask)
2803{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002804 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002805 handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002806}
2807
2808void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2809{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002810 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002811 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002812}
2813
2814void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2815{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002816 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002817 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002818}
2819
2820void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2821{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002822 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002823 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002824}
2825
2826void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2827{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002828 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002829 ASSERT(framebufferObject);
2830
2831 // If a buffer is not present, the clear has no effect
2832 if (framebufferObject->getDepthbuffer() == nullptr &&
2833 framebufferObject->getStencilbuffer() == nullptr)
2834 {
2835 return;
2836 }
2837
Jamie Madillad9f24e2016-02-12 09:27:24 -05002838 syncStateForClear();
Jamie Madillc564c072017-06-01 12:45:42 -04002839 handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002840}
2841
2842void Context::readPixels(GLint x,
2843 GLint y,
2844 GLsizei width,
2845 GLsizei height,
2846 GLenum format,
2847 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002848 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002849{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002850 if (width == 0 || height == 0)
2851 {
2852 return;
2853 }
2854
Jamie Madillad9f24e2016-02-12 09:27:24 -05002855 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002856
Jamie Madillb6664922017-07-25 12:55:04 -04002857 Framebuffer *readFBO = mGLState.getReadFramebuffer();
2858 ASSERT(readFBO);
Jamie Madillc29968b2016-01-20 11:17:23 -05002859
2860 Rectangle area(x, y, width, height);
Jamie Madillb6664922017-07-25 12:55:04 -04002861 handleError(readFBO->readPixels(this, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002862}
2863
2864void Context::copyTexImage2D(GLenum target,
2865 GLint level,
2866 GLenum internalformat,
2867 GLint x,
2868 GLint y,
2869 GLsizei width,
2870 GLsizei height,
2871 GLint border)
2872{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002873 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002874 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002875
Jamie Madillc29968b2016-01-20 11:17:23 -05002876 Rectangle sourceArea(x, y, width, height);
2877
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002878 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002879 Texture *texture =
2880 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002881 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002882}
2883
2884void Context::copyTexSubImage2D(GLenum target,
2885 GLint level,
2886 GLint xoffset,
2887 GLint yoffset,
2888 GLint x,
2889 GLint y,
2890 GLsizei width,
2891 GLsizei height)
2892{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002893 if (width == 0 || height == 0)
2894 {
2895 return;
2896 }
2897
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002898 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002899 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002900
Jamie Madillc29968b2016-01-20 11:17:23 -05002901 Offset destOffset(xoffset, yoffset, 0);
2902 Rectangle sourceArea(x, y, width, height);
2903
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002904 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002905 Texture *texture =
2906 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002907 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002908}
2909
2910void Context::copyTexSubImage3D(GLenum target,
2911 GLint level,
2912 GLint xoffset,
2913 GLint yoffset,
2914 GLint zoffset,
2915 GLint x,
2916 GLint y,
2917 GLsizei width,
2918 GLsizei height)
2919{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002920 if (width == 0 || height == 0)
2921 {
2922 return;
2923 }
2924
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002925 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002926 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002927
Jamie Madillc29968b2016-01-20 11:17:23 -05002928 Offset destOffset(xoffset, yoffset, zoffset);
2929 Rectangle sourceArea(x, y, width, height);
2930
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002931 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002932 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002933 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002934}
2935
2936void Context::framebufferTexture2D(GLenum target,
2937 GLenum attachment,
2938 GLenum textarget,
2939 GLuint texture,
2940 GLint level)
2941{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002942 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002943 ASSERT(framebuffer);
2944
2945 if (texture != 0)
2946 {
2947 Texture *textureObj = getTexture(texture);
2948
2949 ImageIndex index = ImageIndex::MakeInvalid();
2950
2951 if (textarget == GL_TEXTURE_2D)
2952 {
2953 index = ImageIndex::Make2D(level);
2954 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002955 else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE)
2956 {
2957 index = ImageIndex::MakeRectangle(level);
2958 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002959 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2960 {
2961 ASSERT(level == 0);
2962 index = ImageIndex::Make2DMultisample();
2963 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002964 else
2965 {
2966 ASSERT(IsCubeMapTextureTarget(textarget));
2967 index = ImageIndex::MakeCube(textarget, level);
2968 }
2969
Jamie Madilla02315b2017-02-23 14:14:47 -05002970 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002971 }
2972 else
2973 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002974 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002975 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002976
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002977 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002978}
2979
2980void Context::framebufferRenderbuffer(GLenum target,
2981 GLenum attachment,
2982 GLenum renderbuffertarget,
2983 GLuint renderbuffer)
2984{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002985 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002986 ASSERT(framebuffer);
2987
2988 if (renderbuffer != 0)
2989 {
2990 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002991
2992 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002993 renderbufferObject);
2994 }
2995 else
2996 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002997 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002998 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002999
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003000 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003001}
3002
3003void Context::framebufferTextureLayer(GLenum target,
3004 GLenum attachment,
3005 GLuint texture,
3006 GLint level,
3007 GLint layer)
3008{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003009 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003010 ASSERT(framebuffer);
3011
3012 if (texture != 0)
3013 {
3014 Texture *textureObject = getTexture(texture);
3015
3016 ImageIndex index = ImageIndex::MakeInvalid();
3017
3018 if (textureObject->getTarget() == GL_TEXTURE_3D)
3019 {
3020 index = ImageIndex::Make3D(level, layer);
3021 }
3022 else
3023 {
3024 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3025 index = ImageIndex::Make2DArray(level, layer);
3026 }
3027
Jamie Madilla02315b2017-02-23 14:14:47 -05003028 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003029 }
3030 else
3031 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003032 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003033 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003034
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003035 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003036}
3037
Martin Radev137032d2017-07-13 10:11:12 +03003038void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
3039 GLenum attachment,
3040 GLuint texture,
3041 GLint level,
3042 GLint baseViewIndex,
3043 GLsizei numViews)
3044{
Martin Radev82ef7742017-08-08 17:44:58 +03003045 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3046 ASSERT(framebuffer);
3047
3048 if (texture != 0)
3049 {
3050 Texture *textureObj = getTexture(texture);
3051
Martin Radev18b75ba2017-08-15 15:50:40 +03003052 ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
Martin Radev82ef7742017-08-08 17:44:58 +03003053 framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj,
3054 numViews, baseViewIndex);
3055 }
3056 else
3057 {
3058 framebuffer->resetAttachment(this, attachment);
3059 }
3060
3061 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003062}
3063
3064void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
3065 GLenum attachment,
3066 GLuint texture,
3067 GLint level,
3068 GLsizei numViews,
3069 const GLint *viewportOffsets)
3070{
Martin Radev5dae57b2017-07-14 16:15:55 +03003071 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
3072 ASSERT(framebuffer);
3073
3074 if (texture != 0)
3075 {
3076 Texture *textureObj = getTexture(texture);
3077
3078 ImageIndex index = ImageIndex::Make2D(level);
3079 framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index,
3080 textureObj, numViews, viewportOffsets);
3081 }
3082 else
3083 {
3084 framebuffer->resetAttachment(this, attachment);
3085 }
3086
3087 mGLState.setObjectDirty(target);
Martin Radev137032d2017-07-13 10:11:12 +03003088}
3089
Jamie Madillc29968b2016-01-20 11:17:23 -05003090void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3091{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003092 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003093 ASSERT(framebuffer);
3094 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003095 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003096}
3097
3098void Context::readBuffer(GLenum mode)
3099{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003100 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003101 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003102 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003103}
3104
3105void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3106{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003107 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003108 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003109
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003110 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003111 ASSERT(framebuffer);
3112
3113 // The specification isn't clear what should be done when the framebuffer isn't complete.
3114 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill4928b7c2017-06-20 12:57:39 -04003115 handleError(framebuffer->discard(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003116}
3117
3118void Context::invalidateFramebuffer(GLenum target,
3119 GLsizei numAttachments,
3120 const GLenum *attachments)
3121{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003122 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003123 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003124
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003125 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003126 ASSERT(framebuffer);
3127
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003128 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003129 {
Jamie Madill437fa652016-05-03 15:13:24 -04003130 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003131 }
Jamie Madill437fa652016-05-03 15:13:24 -04003132
Jamie Madill4928b7c2017-06-20 12:57:39 -04003133 handleError(framebuffer->invalidate(this, numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003134}
3135
3136void Context::invalidateSubFramebuffer(GLenum target,
3137 GLsizei numAttachments,
3138 const GLenum *attachments,
3139 GLint x,
3140 GLint y,
3141 GLsizei width,
3142 GLsizei height)
3143{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003144 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003145 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003146
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003147 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003148 ASSERT(framebuffer);
3149
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003150 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003151 {
Jamie Madill437fa652016-05-03 15:13:24 -04003152 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003153 }
Jamie Madill437fa652016-05-03 15:13:24 -04003154
3155 Rectangle area(x, y, width, height);
Jamie Madill4928b7c2017-06-20 12:57:39 -04003156 handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003157}
3158
Jamie Madill73a84962016-02-12 09:27:23 -05003159void Context::texImage2D(GLenum target,
3160 GLint level,
3161 GLint internalformat,
3162 GLsizei width,
3163 GLsizei height,
3164 GLint border,
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{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003169 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003170
3171 Extents size(width, height, 1);
3172 Texture *texture =
3173 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003174 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3175 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003176}
3177
3178void Context::texImage3D(GLenum target,
3179 GLint level,
3180 GLint internalformat,
3181 GLsizei width,
3182 GLsizei height,
3183 GLsizei depth,
3184 GLint border,
3185 GLenum format,
3186 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003187 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003188{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003189 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003190
3191 Extents size(width, height, depth);
3192 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003193 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3194 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003195}
3196
3197void Context::texSubImage2D(GLenum target,
3198 GLint level,
3199 GLint xoffset,
3200 GLint yoffset,
3201 GLsizei width,
3202 GLsizei height,
3203 GLenum format,
3204 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003205 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003206{
3207 // Zero sized uploads are valid but no-ops
3208 if (width == 0 || height == 0)
3209 {
3210 return;
3211 }
3212
Jamie Madillad9f24e2016-02-12 09:27:24 -05003213 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003214
3215 Box area(xoffset, yoffset, 0, width, height, 1);
3216 Texture *texture =
3217 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003218 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3219 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003220}
3221
3222void Context::texSubImage3D(GLenum target,
3223 GLint level,
3224 GLint xoffset,
3225 GLint yoffset,
3226 GLint zoffset,
3227 GLsizei width,
3228 GLsizei height,
3229 GLsizei depth,
3230 GLenum format,
3231 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003232 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003233{
3234 // Zero sized uploads are valid but no-ops
3235 if (width == 0 || height == 0 || depth == 0)
3236 {
3237 return;
3238 }
3239
Jamie Madillad9f24e2016-02-12 09:27:24 -05003240 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003241
3242 Box area(xoffset, yoffset, zoffset, width, height, depth);
3243 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003244 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3245 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003246}
3247
3248void Context::compressedTexImage2D(GLenum target,
3249 GLint level,
3250 GLenum internalformat,
3251 GLsizei width,
3252 GLsizei height,
3253 GLint border,
3254 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003255 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003256{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003257 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003258
3259 Extents size(width, height, 1);
3260 Texture *texture =
3261 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003262 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003263 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003264 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003265}
3266
3267void Context::compressedTexImage3D(GLenum target,
3268 GLint level,
3269 GLenum internalformat,
3270 GLsizei width,
3271 GLsizei height,
3272 GLsizei depth,
3273 GLint border,
3274 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003275 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003276{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003277 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003278
3279 Extents size(width, height, depth);
3280 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003281 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003282 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003283 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003284}
3285
3286void Context::compressedTexSubImage2D(GLenum target,
3287 GLint level,
3288 GLint xoffset,
3289 GLint yoffset,
3290 GLsizei width,
3291 GLsizei height,
3292 GLenum format,
3293 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003294 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003295{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003296 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003297
3298 Box area(xoffset, yoffset, 0, width, height, 1);
3299 Texture *texture =
3300 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003301 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003302 format, imageSize,
3303 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003304}
3305
3306void Context::compressedTexSubImage3D(GLenum target,
3307 GLint level,
3308 GLint xoffset,
3309 GLint yoffset,
3310 GLint zoffset,
3311 GLsizei width,
3312 GLsizei height,
3313 GLsizei depth,
3314 GLenum format,
3315 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003316 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003317{
3318 // Zero sized uploads are valid but no-ops
3319 if (width == 0 || height == 0)
3320 {
3321 return;
3322 }
3323
Jamie Madillad9f24e2016-02-12 09:27:24 -05003324 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003325
3326 Box area(xoffset, yoffset, zoffset, width, height, depth);
3327 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003328 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003329 format, imageSize,
3330 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003331}
3332
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003333void Context::generateMipmap(GLenum target)
3334{
3335 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003336 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003337}
3338
Geoff Lang97073d12016-04-20 10:42:34 -07003339void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003340 GLint sourceLevel,
3341 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003342 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003343 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003344 GLint internalFormat,
3345 GLenum destType,
3346 GLboolean unpackFlipY,
3347 GLboolean unpackPremultiplyAlpha,
3348 GLboolean unpackUnmultiplyAlpha)
3349{
3350 syncStateForTexImage();
3351
3352 gl::Texture *sourceTexture = getTexture(sourceId);
3353 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003354 handleError(destTexture->copyTexture(
3355 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3356 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003357}
3358
3359void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003360 GLint sourceLevel,
3361 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003362 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003363 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003364 GLint xoffset,
3365 GLint yoffset,
3366 GLint x,
3367 GLint y,
3368 GLsizei width,
3369 GLsizei height,
3370 GLboolean unpackFlipY,
3371 GLboolean unpackPremultiplyAlpha,
3372 GLboolean unpackUnmultiplyAlpha)
3373{
3374 // Zero sized copies are valid but no-ops
3375 if (width == 0 || height == 0)
3376 {
3377 return;
3378 }
3379
3380 syncStateForTexImage();
3381
3382 gl::Texture *sourceTexture = getTexture(sourceId);
3383 gl::Texture *destTexture = getTexture(destId);
3384 Offset offset(xoffset, yoffset, 0);
3385 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003386 handleError(destTexture->copySubTexture(
3387 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3388 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003389}
3390
Geoff Lang47110bf2016-04-20 11:13:22 -07003391void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3392{
3393 syncStateForTexImage();
3394
3395 gl::Texture *sourceTexture = getTexture(sourceId);
3396 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003397 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003398}
3399
Geoff Lang496c02d2016-10-20 11:38:11 -07003400void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003401{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003402 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003403 ASSERT(buffer);
3404
Geoff Lang496c02d2016-10-20 11:38:11 -07003405 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003406}
3407
Jamie Madill876429b2017-04-20 15:46:24 -04003408void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003409{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003410 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003411 ASSERT(buffer);
3412
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003413 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003414 if (error.isError())
3415 {
Jamie Madill437fa652016-05-03 15:13:24 -04003416 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003417 return nullptr;
3418 }
3419
3420 return buffer->getMapPointer();
3421}
3422
3423GLboolean Context::unmapBuffer(GLenum target)
3424{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003425 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003426 ASSERT(buffer);
3427
3428 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003429 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003430 if (error.isError())
3431 {
Jamie Madill437fa652016-05-03 15:13:24 -04003432 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003433 return GL_FALSE;
3434 }
3435
3436 return result;
3437}
3438
Jamie Madill876429b2017-04-20 15:46:24 -04003439void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003440{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003441 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003442 ASSERT(buffer);
3443
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003444 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003445 if (error.isError())
3446 {
Jamie Madill437fa652016-05-03 15:13:24 -04003447 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003448 return nullptr;
3449 }
3450
3451 return buffer->getMapPointer();
3452}
3453
3454void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3455{
3456 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3457}
3458
Jamie Madillad9f24e2016-02-12 09:27:24 -05003459void Context::syncStateForReadPixels()
3460{
3461 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3462}
3463
3464void Context::syncStateForTexImage()
3465{
3466 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3467}
3468
3469void Context::syncStateForClear()
3470{
3471 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3472}
3473
3474void Context::syncStateForBlit()
3475{
3476 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3477}
3478
Jamie Madillc20ab272016-06-09 07:20:46 -07003479void Context::activeTexture(GLenum texture)
3480{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003481 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003482}
3483
Jamie Madill876429b2017-04-20 15:46:24 -04003484void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003485{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003486 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003487}
3488
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003489void Context::blendEquation(GLenum mode)
3490{
3491 mGLState.setBlendEquation(mode, mode);
3492}
3493
Jamie Madillc20ab272016-06-09 07:20:46 -07003494void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3495{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003496 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003497}
3498
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003499void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3500{
3501 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3502}
3503
Jamie Madillc20ab272016-06-09 07:20:46 -07003504void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3505{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003506 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003507}
3508
Jamie Madill876429b2017-04-20 15:46:24 -04003509void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003510{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003511 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003512}
3513
Jamie Madill876429b2017-04-20 15:46:24 -04003514void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003515{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003516 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003517}
3518
3519void Context::clearStencil(GLint s)
3520{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003521 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003522}
3523
3524void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3525{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003526 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003527}
3528
3529void Context::cullFace(GLenum mode)
3530{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003531 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003532}
3533
3534void Context::depthFunc(GLenum func)
3535{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003536 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003537}
3538
3539void Context::depthMask(GLboolean flag)
3540{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003541 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003542}
3543
Jamie Madill876429b2017-04-20 15:46:24 -04003544void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003545{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003546 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003547}
3548
3549void Context::disable(GLenum cap)
3550{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003551 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003552}
3553
3554void Context::disableVertexAttribArray(GLuint index)
3555{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003556 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003557}
3558
3559void Context::enable(GLenum cap)
3560{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003561 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003562}
3563
3564void Context::enableVertexAttribArray(GLuint index)
3565{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003566 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003567}
3568
3569void Context::frontFace(GLenum mode)
3570{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003571 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003572}
3573
3574void Context::hint(GLenum target, GLenum mode)
3575{
3576 switch (target)
3577 {
3578 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003579 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003580 break;
3581
3582 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003583 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003584 break;
3585
3586 default:
3587 UNREACHABLE();
3588 return;
3589 }
3590}
3591
3592void Context::lineWidth(GLfloat width)
3593{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003594 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003595}
3596
3597void Context::pixelStorei(GLenum pname, GLint param)
3598{
3599 switch (pname)
3600 {
3601 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003602 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003603 break;
3604
3605 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003606 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003607 break;
3608
3609 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003610 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003611 break;
3612
3613 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003614 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003615 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003616 break;
3617
3618 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003619 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003620 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003621 break;
3622
3623 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003624 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003625 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003626 break;
3627
3628 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003629 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003630 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003631 break;
3632
3633 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003634 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003635 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003636 break;
3637
3638 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003639 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003640 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003641 break;
3642
3643 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003644 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003645 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003646 break;
3647
3648 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003649 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003650 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003651 break;
3652
3653 default:
3654 UNREACHABLE();
3655 return;
3656 }
3657}
3658
3659void Context::polygonOffset(GLfloat factor, GLfloat units)
3660{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003661 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003662}
3663
Jamie Madill876429b2017-04-20 15:46:24 -04003664void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003665{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003666 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003667}
3668
3669void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3670{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003671 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003672}
3673
3674void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3675{
3676 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3677 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003678 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003679 }
3680
3681 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3682 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003683 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003684 }
3685}
3686
3687void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3688{
3689 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3690 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003691 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003692 }
3693
3694 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3695 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003696 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003697 }
3698}
3699
3700void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3701{
3702 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3703 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003704 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003705 }
3706
3707 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3708 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003709 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003710 }
3711}
3712
3713void Context::vertexAttrib1f(GLuint index, GLfloat x)
3714{
3715 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003716 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003717}
3718
3719void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3720{
3721 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003722 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003723}
3724
3725void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3726{
3727 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003728 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003729}
3730
3731void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3732{
3733 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003734 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003735}
3736
3737void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3738{
3739 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003740 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003741}
3742
3743void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3744{
3745 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003746 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003747}
3748
3749void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3750{
3751 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003752 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003753}
3754
3755void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3756{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003757 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003758}
3759
3760void Context::vertexAttribPointer(GLuint index,
3761 GLint size,
3762 GLenum type,
3763 GLboolean normalized,
3764 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003765 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003766{
Shaodde78e82017-05-22 14:13:27 +08003767 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3768 type, normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003769}
3770
Shao80957d92017-02-20 21:25:59 +08003771void Context::vertexAttribFormat(GLuint attribIndex,
3772 GLint size,
3773 GLenum type,
3774 GLboolean normalized,
3775 GLuint relativeOffset)
3776{
3777 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3778 relativeOffset);
3779}
3780
3781void Context::vertexAttribIFormat(GLuint attribIndex,
3782 GLint size,
3783 GLenum type,
3784 GLuint relativeOffset)
3785{
3786 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3787}
3788
3789void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3790{
Shaodde78e82017-05-22 14:13:27 +08003791 mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08003792}
3793
3794void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3795{
3796 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3797}
3798
Jamie Madillc20ab272016-06-09 07:20:46 -07003799void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3800{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003801 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003802}
3803
3804void Context::vertexAttribIPointer(GLuint index,
3805 GLint size,
3806 GLenum type,
3807 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003808 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003809{
Shaodde78e82017-05-22 14:13:27 +08003810 mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size,
3811 type, false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003812}
3813
3814void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3815{
3816 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003817 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003818}
3819
3820void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3821{
3822 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003823 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003824}
3825
3826void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3827{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003828 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003829}
3830
3831void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3832{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003833 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003834}
3835
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003836void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3837{
3838 const VertexAttribCurrentValueData &currentValues =
3839 getGLState().getVertexAttribCurrentValue(index);
3840 const VertexArray *vao = getGLState().getVertexArray();
3841 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3842 currentValues, pname, params);
3843}
3844
3845void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3846{
3847 const VertexAttribCurrentValueData &currentValues =
3848 getGLState().getVertexAttribCurrentValue(index);
3849 const VertexArray *vao = getGLState().getVertexArray();
3850 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3851 currentValues, pname, params);
3852}
3853
3854void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3855{
3856 const VertexAttribCurrentValueData &currentValues =
3857 getGLState().getVertexAttribCurrentValue(index);
3858 const VertexArray *vao = getGLState().getVertexArray();
3859 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3860 currentValues, pname, params);
3861}
3862
3863void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3864{
3865 const VertexAttribCurrentValueData &currentValues =
3866 getGLState().getVertexAttribCurrentValue(index);
3867 const VertexArray *vao = getGLState().getVertexArray();
3868 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3869 currentValues, pname, params);
3870}
3871
Jamie Madill876429b2017-04-20 15:46:24 -04003872void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003873{
3874 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3875 QueryVertexAttribPointerv(attrib, pname, pointer);
3876}
3877
Jamie Madillc20ab272016-06-09 07:20:46 -07003878void Context::debugMessageControl(GLenum source,
3879 GLenum type,
3880 GLenum severity,
3881 GLsizei count,
3882 const GLuint *ids,
3883 GLboolean enabled)
3884{
3885 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003886 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3887 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003888}
3889
3890void Context::debugMessageInsert(GLenum source,
3891 GLenum type,
3892 GLuint id,
3893 GLenum severity,
3894 GLsizei length,
3895 const GLchar *buf)
3896{
3897 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003898 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003899}
3900
3901void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3902{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003903 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003904}
3905
3906GLuint Context::getDebugMessageLog(GLuint count,
3907 GLsizei bufSize,
3908 GLenum *sources,
3909 GLenum *types,
3910 GLuint *ids,
3911 GLenum *severities,
3912 GLsizei *lengths,
3913 GLchar *messageLog)
3914{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003915 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3916 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003917}
3918
3919void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3920{
3921 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003922 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003923}
3924
3925void Context::popDebugGroup()
3926{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003927 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003928}
3929
Jamie Madill876429b2017-04-20 15:46:24 -04003930void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003931{
3932 Buffer *buffer = mGLState.getTargetBuffer(target);
3933 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003934 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003935}
3936
Jamie Madill876429b2017-04-20 15:46:24 -04003937void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003938{
3939 if (data == nullptr)
3940 {
3941 return;
3942 }
3943
3944 Buffer *buffer = mGLState.getTargetBuffer(target);
3945 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003946 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003947}
3948
Jamie Madillef300b12016-10-07 15:12:09 -04003949void Context::attachShader(GLuint program, GLuint shader)
3950{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003951 auto programObject = mState.mShaderPrograms->getProgram(program);
3952 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003953 ASSERT(programObject && shaderObject);
3954 programObject->attachShader(shaderObject);
3955}
3956
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003957const Workarounds &Context::getWorkarounds() const
3958{
3959 return mWorkarounds;
3960}
3961
Jamie Madillb0817d12016-11-01 15:48:31 -04003962void Context::copyBufferSubData(GLenum readTarget,
3963 GLenum writeTarget,
3964 GLintptr readOffset,
3965 GLintptr writeOffset,
3966 GLsizeiptr size)
3967{
3968 // if size is zero, the copy is a successful no-op
3969 if (size == 0)
3970 {
3971 return;
3972 }
3973
3974 // TODO(jmadill): cache these.
3975 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3976 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3977
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003978 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003979}
3980
Jamie Madill01a80ee2016-11-07 12:06:18 -05003981void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3982{
3983 Program *programObject = getProgram(program);
3984 // TODO(jmadill): Re-use this from the validation if possible.
3985 ASSERT(programObject);
3986 programObject->bindAttributeLocation(index, name);
3987}
3988
3989void Context::bindBuffer(GLenum target, GLuint buffer)
3990{
3991 switch (target)
3992 {
3993 case GL_ARRAY_BUFFER:
3994 bindArrayBuffer(buffer);
3995 break;
3996 case GL_ELEMENT_ARRAY_BUFFER:
3997 bindElementArrayBuffer(buffer);
3998 break;
3999 case GL_COPY_READ_BUFFER:
4000 bindCopyReadBuffer(buffer);
4001 break;
4002 case GL_COPY_WRITE_BUFFER:
4003 bindCopyWriteBuffer(buffer);
4004 break;
4005 case GL_PIXEL_PACK_BUFFER:
4006 bindPixelPackBuffer(buffer);
4007 break;
4008 case GL_PIXEL_UNPACK_BUFFER:
4009 bindPixelUnpackBuffer(buffer);
4010 break;
4011 case GL_UNIFORM_BUFFER:
4012 bindGenericUniformBuffer(buffer);
4013 break;
4014 case GL_TRANSFORM_FEEDBACK_BUFFER:
4015 bindGenericTransformFeedbackBuffer(buffer);
4016 break;
Geoff Lang3b573612016-10-31 14:08:10 -04004017 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08004018 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004019 break;
4020 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004021 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004022 break;
4023 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08004024 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04004025 break;
4026 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05004027 if (buffer != 0)
4028 {
4029 // Binding buffers to this binding point is not implemented yet.
4030 UNIMPLEMENTED();
4031 }
Geoff Lang3b573612016-10-31 14:08:10 -04004032 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05004033
4034 default:
4035 UNREACHABLE();
4036 break;
4037 }
4038}
4039
Jiajia Qin6eafb042016-12-27 17:04:07 +08004040void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
4041{
4042 bindBufferRange(target, index, buffer, 0, 0);
4043}
4044
4045void Context::bindBufferRange(GLenum target,
4046 GLuint index,
4047 GLuint buffer,
4048 GLintptr offset,
4049 GLsizeiptr size)
4050{
4051 switch (target)
4052 {
4053 case GL_TRANSFORM_FEEDBACK_BUFFER:
4054 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
4055 bindGenericTransformFeedbackBuffer(buffer);
4056 break;
4057 case GL_UNIFORM_BUFFER:
4058 bindIndexedUniformBuffer(buffer, index, offset, size);
4059 bindGenericUniformBuffer(buffer);
4060 break;
4061 case GL_ATOMIC_COUNTER_BUFFER:
4062 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4063 bindGenericAtomicCounterBuffer(buffer);
4064 break;
4065 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004066 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4067 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004068 break;
4069 default:
4070 UNREACHABLE();
4071 break;
4072 }
4073}
4074
Jamie Madill01a80ee2016-11-07 12:06:18 -05004075void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4076{
4077 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4078 {
4079 bindReadFramebuffer(framebuffer);
4080 }
4081
4082 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4083 {
4084 bindDrawFramebuffer(framebuffer);
4085 }
4086}
4087
4088void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4089{
4090 ASSERT(target == GL_RENDERBUFFER);
4091 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004092 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill4928b7c2017-06-20 12:57:39 -04004093 mGLState.setRenderbufferBinding(this, object);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004094}
4095
JiangYizhoubddc46b2016-12-09 09:50:51 +08004096void Context::texStorage2DMultisample(GLenum target,
4097 GLsizei samples,
4098 GLenum internalformat,
4099 GLsizei width,
4100 GLsizei height,
4101 GLboolean fixedsamplelocations)
4102{
4103 Extents size(width, height, 1);
4104 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004105 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004106 fixedsamplelocations));
4107}
4108
4109void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4110{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004111 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004112 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4113
4114 switch (pname)
4115 {
4116 case GL_SAMPLE_POSITION:
4117 handleError(framebuffer->getSamplePosition(index, val));
4118 break;
4119 default:
4120 UNREACHABLE();
4121 }
4122}
4123
Jamie Madille8fb6402017-02-14 17:56:40 -05004124void Context::renderbufferStorage(GLenum target,
4125 GLenum internalformat,
4126 GLsizei width,
4127 GLsizei height)
4128{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004129 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4130 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4131
Jamie Madille8fb6402017-02-14 17:56:40 -05004132 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4928b7c2017-06-20 12:57:39 -04004133 handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004134}
4135
4136void Context::renderbufferStorageMultisample(GLenum target,
4137 GLsizei samples,
4138 GLenum internalformat,
4139 GLsizei width,
4140 GLsizei height)
4141{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004142 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4143 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004144
4145 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004146 handleError(
Jamie Madill4928b7c2017-06-20 12:57:39 -04004147 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004148}
4149
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004150void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4151{
4152 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004153 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004154}
4155
JiangYizhoue18e6392017-02-20 10:32:23 +08004156void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4157{
4158 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4159 QueryFramebufferParameteriv(framebuffer, pname, params);
4160}
4161
4162void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4163{
4164 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4165 SetFramebufferParameteri(framebuffer, pname, param);
4166}
4167
Jamie Madillb3f26b92017-07-19 15:07:41 -04004168Error Context::getScratchBuffer(size_t requstedSizeBytes,
4169 angle::MemoryBuffer **scratchBufferOut) const
Jamie Madille14951e2017-03-09 18:55:16 -05004170{
Jamie Madillb3f26b92017-07-19 15:07:41 -04004171 if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut))
4172 {
4173 return OutOfMemory() << "Failed to allocate internal buffer.";
4174 }
4175 return NoError();
4176}
4177
4178Error Context::getZeroFilledBuffer(size_t requstedSizeBytes,
4179 angle::MemoryBuffer **zeroBufferOut) const
4180{
4181 if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0))
Jamie Madille14951e2017-03-09 18:55:16 -05004182 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004183 return OutOfMemory() << "Failed to allocate internal buffer.";
Jamie Madille14951e2017-03-09 18:55:16 -05004184 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004185 return NoError();
Jamie Madille14951e2017-03-09 18:55:16 -05004186}
4187
Xinghua Cao2b396592017-03-29 15:36:04 +08004188void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4189{
4190 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4191 {
4192 return;
4193 }
4194
Jamie Madillfe548342017-06-19 11:13:24 -04004195 mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
Xinghua Cao2b396592017-03-29 15:36:04 +08004196}
4197
JiangYizhou165361c2017-06-07 14:56:57 +08004198void Context::texStorage2D(GLenum target,
4199 GLsizei levels,
4200 GLenum internalFormat,
4201 GLsizei width,
4202 GLsizei height)
4203{
4204 Extents size(width, height, 1);
4205 Texture *texture = getTargetTexture(target);
4206 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4207}
4208
4209void Context::texStorage3D(GLenum target,
4210 GLsizei levels,
4211 GLenum internalFormat,
4212 GLsizei width,
4213 GLsizei height,
4214 GLsizei depth)
4215{
4216 Extents size(width, height, depth);
4217 Texture *texture = getTargetTexture(target);
4218 handleError(texture->setStorage(this, target, levels, internalFormat, size));
4219}
4220
Jamie Madillc1d770e2017-04-13 17:31:24 -04004221GLenum Context::checkFramebufferStatus(GLenum target)
4222{
4223 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4224 ASSERT(framebuffer);
4225
4226 return framebuffer->checkStatus(this);
4227}
4228
4229void Context::compileShader(GLuint shader)
4230{
4231 Shader *shaderObject = GetValidShader(this, shader);
4232 if (!shaderObject)
4233 {
4234 return;
4235 }
4236 shaderObject->compile(this);
4237}
4238
4239void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4240{
4241 for (int i = 0; i < n; i++)
4242 {
4243 deleteBuffer(buffers[i]);
4244 }
4245}
4246
4247void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4248{
4249 for (int i = 0; i < n; i++)
4250 {
4251 if (framebuffers[i] != 0)
4252 {
4253 deleteFramebuffer(framebuffers[i]);
4254 }
4255 }
4256}
4257
4258void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4259{
4260 for (int i = 0; i < n; i++)
4261 {
4262 deleteRenderbuffer(renderbuffers[i]);
4263 }
4264}
4265
4266void Context::deleteTextures(GLsizei n, const GLuint *textures)
4267{
4268 for (int i = 0; i < n; i++)
4269 {
4270 if (textures[i] != 0)
4271 {
4272 deleteTexture(textures[i]);
4273 }
4274 }
4275}
4276
4277void Context::detachShader(GLuint program, GLuint shader)
4278{
4279 Program *programObject = getProgram(program);
4280 ASSERT(programObject);
4281
4282 Shader *shaderObject = getShader(shader);
4283 ASSERT(shaderObject);
4284
4285 programObject->detachShader(this, shaderObject);
4286}
4287
4288void Context::genBuffers(GLsizei n, GLuint *buffers)
4289{
4290 for (int i = 0; i < n; i++)
4291 {
4292 buffers[i] = createBuffer();
4293 }
4294}
4295
4296void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4297{
4298 for (int i = 0; i < n; i++)
4299 {
4300 framebuffers[i] = createFramebuffer();
4301 }
4302}
4303
4304void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4305{
4306 for (int i = 0; i < n; i++)
4307 {
4308 renderbuffers[i] = createRenderbuffer();
4309 }
4310}
4311
4312void Context::genTextures(GLsizei n, GLuint *textures)
4313{
4314 for (int i = 0; i < n; i++)
4315 {
4316 textures[i] = createTexture();
4317 }
4318}
4319
4320void Context::getActiveAttrib(GLuint program,
4321 GLuint index,
4322 GLsizei bufsize,
4323 GLsizei *length,
4324 GLint *size,
4325 GLenum *type,
4326 GLchar *name)
4327{
4328 Program *programObject = getProgram(program);
4329 ASSERT(programObject);
4330 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4331}
4332
4333void Context::getActiveUniform(GLuint program,
4334 GLuint index,
4335 GLsizei bufsize,
4336 GLsizei *length,
4337 GLint *size,
4338 GLenum *type,
4339 GLchar *name)
4340{
4341 Program *programObject = getProgram(program);
4342 ASSERT(programObject);
4343 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4344}
4345
4346void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4347{
4348 Program *programObject = getProgram(program);
4349 ASSERT(programObject);
4350 programObject->getAttachedShaders(maxcount, count, shaders);
4351}
4352
4353GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4354{
4355 Program *programObject = getProgram(program);
4356 ASSERT(programObject);
4357 return programObject->getAttributeLocation(name);
4358}
4359
4360void Context::getBooleanv(GLenum pname, GLboolean *params)
4361{
4362 GLenum nativeType;
4363 unsigned int numParams = 0;
4364 getQueryParameterInfo(pname, &nativeType, &numParams);
4365
4366 if (nativeType == GL_BOOL)
4367 {
4368 getBooleanvImpl(pname, params);
4369 }
4370 else
4371 {
4372 CastStateValues(this, nativeType, pname, numParams, params);
4373 }
4374}
4375
4376void Context::getFloatv(GLenum pname, GLfloat *params)
4377{
4378 GLenum nativeType;
4379 unsigned int numParams = 0;
4380 getQueryParameterInfo(pname, &nativeType, &numParams);
4381
4382 if (nativeType == GL_FLOAT)
4383 {
4384 getFloatvImpl(pname, params);
4385 }
4386 else
4387 {
4388 CastStateValues(this, nativeType, pname, numParams, params);
4389 }
4390}
4391
4392void Context::getIntegerv(GLenum pname, GLint *params)
4393{
4394 GLenum nativeType;
4395 unsigned int numParams = 0;
4396 getQueryParameterInfo(pname, &nativeType, &numParams);
4397
4398 if (nativeType == GL_INT)
4399 {
4400 getIntegervImpl(pname, params);
4401 }
4402 else
4403 {
4404 CastStateValues(this, nativeType, pname, numParams, params);
4405 }
4406}
4407
4408void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4409{
4410 Program *programObject = getProgram(program);
4411 ASSERT(programObject);
Jamie Madillffe00c02017-06-27 16:26:55 -04004412 QueryProgramiv(this, programObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004413}
4414
Jamie Madillbe849e42017-05-02 15:49:00 -04004415void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004416{
4417 Program *programObject = getProgram(program);
4418 ASSERT(programObject);
4419 programObject->getInfoLog(bufsize, length, infolog);
4420}
4421
4422void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4423{
4424 Shader *shaderObject = getShader(shader);
4425 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004426 QueryShaderiv(this, shaderObject, pname, params);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004427}
4428
4429void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4430{
4431 Shader *shaderObject = getShader(shader);
4432 ASSERT(shaderObject);
Jamie Madillbd044ed2017-06-05 12:59:21 -04004433 shaderObject->getInfoLog(this, bufsize, length, infolog);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004434}
4435
4436void Context::getShaderPrecisionFormat(GLenum shadertype,
4437 GLenum precisiontype,
4438 GLint *range,
4439 GLint *precision)
4440{
4441 // TODO(jmadill): Compute shaders.
4442
4443 switch (shadertype)
4444 {
4445 case GL_VERTEX_SHADER:
4446 switch (precisiontype)
4447 {
4448 case GL_LOW_FLOAT:
4449 mCaps.vertexLowpFloat.get(range, precision);
4450 break;
4451 case GL_MEDIUM_FLOAT:
4452 mCaps.vertexMediumpFloat.get(range, precision);
4453 break;
4454 case GL_HIGH_FLOAT:
4455 mCaps.vertexHighpFloat.get(range, precision);
4456 break;
4457
4458 case GL_LOW_INT:
4459 mCaps.vertexLowpInt.get(range, precision);
4460 break;
4461 case GL_MEDIUM_INT:
4462 mCaps.vertexMediumpInt.get(range, precision);
4463 break;
4464 case GL_HIGH_INT:
4465 mCaps.vertexHighpInt.get(range, precision);
4466 break;
4467
4468 default:
4469 UNREACHABLE();
4470 return;
4471 }
4472 break;
4473
4474 case GL_FRAGMENT_SHADER:
4475 switch (precisiontype)
4476 {
4477 case GL_LOW_FLOAT:
4478 mCaps.fragmentLowpFloat.get(range, precision);
4479 break;
4480 case GL_MEDIUM_FLOAT:
4481 mCaps.fragmentMediumpFloat.get(range, precision);
4482 break;
4483 case GL_HIGH_FLOAT:
4484 mCaps.fragmentHighpFloat.get(range, precision);
4485 break;
4486
4487 case GL_LOW_INT:
4488 mCaps.fragmentLowpInt.get(range, precision);
4489 break;
4490 case GL_MEDIUM_INT:
4491 mCaps.fragmentMediumpInt.get(range, precision);
4492 break;
4493 case GL_HIGH_INT:
4494 mCaps.fragmentHighpInt.get(range, precision);
4495 break;
4496
4497 default:
4498 UNREACHABLE();
4499 return;
4500 }
4501 break;
4502
4503 default:
4504 UNREACHABLE();
4505 return;
4506 }
4507}
4508
4509void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4510{
4511 Shader *shaderObject = getShader(shader);
4512 ASSERT(shaderObject);
4513 shaderObject->getSource(bufsize, length, source);
4514}
4515
4516void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4517{
4518 Program *programObject = getProgram(program);
4519 ASSERT(programObject);
4520 programObject->getUniformfv(location, params);
4521}
4522
4523void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4524{
4525 Program *programObject = getProgram(program);
4526 ASSERT(programObject);
4527 programObject->getUniformiv(location, params);
4528}
4529
4530GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4531{
4532 Program *programObject = getProgram(program);
4533 ASSERT(programObject);
4534 return programObject->getUniformLocation(name);
4535}
4536
4537GLboolean Context::isBuffer(GLuint buffer)
4538{
4539 if (buffer == 0)
4540 {
4541 return GL_FALSE;
4542 }
4543
4544 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4545}
4546
4547GLboolean Context::isEnabled(GLenum cap)
4548{
4549 return mGLState.getEnableFeature(cap);
4550}
4551
4552GLboolean Context::isFramebuffer(GLuint framebuffer)
4553{
4554 if (framebuffer == 0)
4555 {
4556 return GL_FALSE;
4557 }
4558
4559 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4560}
4561
4562GLboolean Context::isProgram(GLuint program)
4563{
4564 if (program == 0)
4565 {
4566 return GL_FALSE;
4567 }
4568
4569 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4570}
4571
4572GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4573{
4574 if (renderbuffer == 0)
4575 {
4576 return GL_FALSE;
4577 }
4578
4579 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4580}
4581
4582GLboolean Context::isShader(GLuint shader)
4583{
4584 if (shader == 0)
4585 {
4586 return GL_FALSE;
4587 }
4588
4589 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4590}
4591
4592GLboolean Context::isTexture(GLuint texture)
4593{
4594 if (texture == 0)
4595 {
4596 return GL_FALSE;
4597 }
4598
4599 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4600}
4601
4602void Context::linkProgram(GLuint program)
4603{
4604 Program *programObject = getProgram(program);
4605 ASSERT(programObject);
4606 handleError(programObject->link(this));
4607}
4608
4609void Context::releaseShaderCompiler()
4610{
Jamie Madill4928b7c2017-06-20 12:57:39 -04004611 mCompiler.set(this, nullptr);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004612}
4613
4614void Context::shaderBinary(GLsizei n,
4615 const GLuint *shaders,
4616 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004617 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004618 GLsizei length)
4619{
4620 // No binary shader formats are supported.
4621 UNIMPLEMENTED();
4622}
4623
4624void Context::shaderSource(GLuint shader,
4625 GLsizei count,
4626 const GLchar *const *string,
4627 const GLint *length)
4628{
4629 Shader *shaderObject = getShader(shader);
4630 ASSERT(shaderObject);
4631 shaderObject->setSource(count, string, length);
4632}
4633
4634void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4635{
4636 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4637}
4638
4639void Context::stencilMask(GLuint mask)
4640{
4641 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4642}
4643
4644void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4645{
4646 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4647}
4648
4649void Context::uniform1f(GLint location, GLfloat x)
4650{
4651 Program *program = mGLState.getProgram();
4652 program->setUniform1fv(location, 1, &x);
4653}
4654
4655void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4656{
4657 Program *program = mGLState.getProgram();
4658 program->setUniform1fv(location, count, v);
4659}
4660
4661void Context::uniform1i(GLint location, GLint x)
4662{
4663 Program *program = mGLState.getProgram();
4664 program->setUniform1iv(location, 1, &x);
4665}
4666
4667void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4668{
4669 Program *program = mGLState.getProgram();
4670 program->setUniform1iv(location, count, v);
4671}
4672
4673void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4674{
4675 GLfloat xy[2] = {x, y};
4676 Program *program = mGLState.getProgram();
4677 program->setUniform2fv(location, 1, xy);
4678}
4679
4680void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4681{
4682 Program *program = mGLState.getProgram();
4683 program->setUniform2fv(location, count, v);
4684}
4685
4686void Context::uniform2i(GLint location, GLint x, GLint y)
4687{
4688 GLint xy[2] = {x, y};
4689 Program *program = mGLState.getProgram();
4690 program->setUniform2iv(location, 1, xy);
4691}
4692
4693void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4694{
4695 Program *program = mGLState.getProgram();
4696 program->setUniform2iv(location, count, v);
4697}
4698
4699void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4700{
4701 GLfloat xyz[3] = {x, y, z};
4702 Program *program = mGLState.getProgram();
4703 program->setUniform3fv(location, 1, xyz);
4704}
4705
4706void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4707{
4708 Program *program = mGLState.getProgram();
4709 program->setUniform3fv(location, count, v);
4710}
4711
4712void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4713{
4714 GLint xyz[3] = {x, y, z};
4715 Program *program = mGLState.getProgram();
4716 program->setUniform3iv(location, 1, xyz);
4717}
4718
4719void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4720{
4721 Program *program = mGLState.getProgram();
4722 program->setUniform3iv(location, count, v);
4723}
4724
4725void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4726{
4727 GLfloat xyzw[4] = {x, y, z, w};
4728 Program *program = mGLState.getProgram();
4729 program->setUniform4fv(location, 1, xyzw);
4730}
4731
4732void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4733{
4734 Program *program = mGLState.getProgram();
4735 program->setUniform4fv(location, count, v);
4736}
4737
4738void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4739{
4740 GLint xyzw[4] = {x, y, z, w};
4741 Program *program = mGLState.getProgram();
4742 program->setUniform4iv(location, 1, xyzw);
4743}
4744
4745void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4746{
4747 Program *program = mGLState.getProgram();
4748 program->setUniform4iv(location, count, v);
4749}
4750
4751void Context::uniformMatrix2fv(GLint location,
4752 GLsizei count,
4753 GLboolean transpose,
4754 const GLfloat *value)
4755{
4756 Program *program = mGLState.getProgram();
4757 program->setUniformMatrix2fv(location, count, transpose, value);
4758}
4759
4760void Context::uniformMatrix3fv(GLint location,
4761 GLsizei count,
4762 GLboolean transpose,
4763 const GLfloat *value)
4764{
4765 Program *program = mGLState.getProgram();
4766 program->setUniformMatrix3fv(location, count, transpose, value);
4767}
4768
4769void Context::uniformMatrix4fv(GLint location,
4770 GLsizei count,
4771 GLboolean transpose,
4772 const GLfloat *value)
4773{
4774 Program *program = mGLState.getProgram();
4775 program->setUniformMatrix4fv(location, count, transpose, value);
4776}
4777
4778void Context::validateProgram(GLuint program)
4779{
4780 Program *programObject = getProgram(program);
4781 ASSERT(programObject);
4782 programObject->validate(mCaps);
4783}
4784
Jamie Madilld04908b2017-06-09 14:15:35 -04004785void Context::getProgramBinary(GLuint program,
4786 GLsizei bufSize,
4787 GLsizei *length,
4788 GLenum *binaryFormat,
4789 void *binary)
4790{
4791 Program *programObject = getProgram(program);
4792 ASSERT(programObject != nullptr);
4793
4794 handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
4795}
4796
4797void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
4798{
4799 Program *programObject = getProgram(program);
4800 ASSERT(programObject != nullptr);
Jamie Madillb6664922017-07-25 12:55:04 -04004801
Jamie Madilld04908b2017-06-09 14:15:35 -04004802 handleError(programObject->loadBinary(this, binaryFormat, binary, length));
4803}
4804
Jamie Madillff325f12017-08-26 15:06:05 -04004805void Context::uniform1ui(GLint location, GLuint v0)
4806{
4807 Program *program = mGLState.getProgram();
4808 program->setUniform1uiv(location, 1, &v0);
4809}
4810
4811void Context::uniform2ui(GLint location, GLuint v0, GLuint v1)
4812{
4813 Program *program = mGLState.getProgram();
4814 const GLuint xy[] = {v0, v1};
4815 program->setUniform2uiv(location, 1, xy);
4816}
4817
4818void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
4819{
4820 Program *program = mGLState.getProgram();
4821 const GLuint xyz[] = {v0, v1, v2};
4822 program->setUniform3uiv(location, 1, xyz);
4823}
4824
4825void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
4826{
4827 Program *program = mGLState.getProgram();
4828 const GLuint xyzw[] = {v0, v1, v2, v3};
4829 program->setUniform4uiv(location, 1, xyzw);
4830}
4831
4832void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value)
4833{
4834 Program *program = mGLState.getProgram();
4835 program->setUniform1uiv(location, count, value);
4836}
4837void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value)
4838{
4839 Program *program = mGLState.getProgram();
4840 program->setUniform2uiv(location, count, value);
4841}
4842
4843void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value)
4844{
4845 Program *program = mGLState.getProgram();
4846 program->setUniform3uiv(location, count, value);
4847}
4848
4849void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value)
4850{
4851 Program *program = mGLState.getProgram();
4852 program->setUniform4uiv(location, count, value);
4853}
4854
Jamie Madillf0e04492017-08-26 15:28:42 -04004855void Context::genQueries(GLsizei n, GLuint *ids)
4856{
4857 for (GLsizei i = 0; i < n; i++)
4858 {
4859 GLuint handle = mQueryHandleAllocator.allocate();
4860 mQueryMap.assign(handle, nullptr);
4861 ids[i] = handle;
4862 }
4863}
4864
4865void Context::deleteQueries(GLsizei n, const GLuint *ids)
4866{
4867 for (int i = 0; i < n; i++)
4868 {
4869 GLuint query = ids[i];
4870
4871 Query *queryObject = nullptr;
4872 if (mQueryMap.erase(query, &queryObject))
4873 {
4874 mQueryHandleAllocator.release(query);
4875 if (queryObject)
4876 {
4877 queryObject->release(this);
4878 }
4879 }
4880 }
4881}
4882
4883GLboolean Context::isQuery(GLuint id)
4884{
4885 return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE;
4886}
4887
Jamie Madillc8c95812017-08-26 18:40:09 -04004888void Context::uniformMatrix2x3fv(GLint location,
4889 GLsizei count,
4890 GLboolean transpose,
4891 const GLfloat *value)
4892{
4893 Program *program = mGLState.getProgram();
4894 program->setUniformMatrix2x3fv(location, count, transpose, value);
4895}
4896
4897void Context::uniformMatrix3x2fv(GLint location,
4898 GLsizei count,
4899 GLboolean transpose,
4900 const GLfloat *value)
4901{
4902 Program *program = mGLState.getProgram();
4903 program->setUniformMatrix3x2fv(location, count, transpose, value);
4904}
4905
4906void Context::uniformMatrix2x4fv(GLint location,
4907 GLsizei count,
4908 GLboolean transpose,
4909 const GLfloat *value)
4910{
4911 Program *program = mGLState.getProgram();
4912 program->setUniformMatrix2x4fv(location, count, transpose, value);
4913}
4914
4915void Context::uniformMatrix4x2fv(GLint location,
4916 GLsizei count,
4917 GLboolean transpose,
4918 const GLfloat *value)
4919{
4920 Program *program = mGLState.getProgram();
4921 program->setUniformMatrix4x2fv(location, count, transpose, value);
4922}
4923
4924void Context::uniformMatrix3x4fv(GLint location,
4925 GLsizei count,
4926 GLboolean transpose,
4927 const GLfloat *value)
4928{
4929 Program *program = mGLState.getProgram();
4930 program->setUniformMatrix3x4fv(location, count, transpose, value);
4931}
4932
4933void Context::uniformMatrix4x3fv(GLint location,
4934 GLsizei count,
4935 GLboolean transpose,
4936 const GLfloat *value)
4937{
4938 Program *program = mGLState.getProgram();
4939 program->setUniformMatrix4x3fv(location, count, transpose, value);
4940}
4941
Jamie Madilld7576732017-08-26 18:49:50 -04004942void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays)
4943{
4944 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4945 {
4946 GLuint vertexArray = arrays[arrayIndex];
4947
4948 if (arrays[arrayIndex] != 0)
4949 {
4950 VertexArray *vertexArrayObject = nullptr;
4951 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
4952 {
4953 if (vertexArrayObject != nullptr)
4954 {
4955 detachVertexArray(vertexArray);
4956 vertexArrayObject->onDestroy(this);
4957 }
4958
4959 mVertexArrayHandleAllocator.release(vertexArray);
4960 }
4961 }
4962 }
4963}
4964
4965void Context::genVertexArrays(GLsizei n, GLuint *arrays)
4966{
4967 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
4968 {
4969 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
4970 mVertexArrayMap.assign(vertexArray, nullptr);
4971 arrays[arrayIndex] = vertexArray;
4972 }
4973}
4974
4975bool Context::isVertexArray(GLuint array)
4976{
4977 if (array == 0)
4978 {
4979 return GL_FALSE;
4980 }
4981
4982 VertexArray *vao = getVertexArray(array);
4983 return (vao != nullptr ? GL_TRUE : GL_FALSE);
4984}
4985
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04004986void Context::endTransformFeedback()
4987{
4988 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
4989 transformFeedback->end(this);
4990}
4991
4992void Context::transformFeedbackVaryings(GLuint program,
4993 GLsizei count,
4994 const GLchar *const *varyings,
4995 GLenum bufferMode)
4996{
4997 Program *programObject = getProgram(program);
4998 ASSERT(programObject);
4999 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
5000}
5001
5002void Context::getTransformFeedbackVarying(GLuint program,
5003 GLuint index,
5004 GLsizei bufSize,
5005 GLsizei *length,
5006 GLsizei *size,
5007 GLenum *type,
5008 GLchar *name)
5009{
5010 Program *programObject = getProgram(program);
5011 ASSERT(programObject);
5012 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
5013}
5014
5015void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids)
5016{
5017 for (int i = 0; i < n; i++)
5018 {
5019 GLuint transformFeedback = ids[i];
5020 if (transformFeedback == 0)
5021 {
5022 continue;
5023 }
5024
5025 TransformFeedback *transformFeedbackObject = nullptr;
5026 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
5027 {
5028 if (transformFeedbackObject != nullptr)
5029 {
5030 detachTransformFeedback(transformFeedback);
5031 transformFeedbackObject->release(this);
5032 }
5033
5034 mTransformFeedbackHandleAllocator.release(transformFeedback);
5035 }
5036 }
5037}
5038
5039void Context::genTransformFeedbacks(GLsizei n, GLuint *ids)
5040{
5041 for (int i = 0; i < n; i++)
5042 {
5043 GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate();
5044 mTransformFeedbackMap.assign(transformFeedback, nullptr);
5045 ids[i] = transformFeedback;
5046 }
5047}
5048
5049bool Context::isTransformFeedback(GLuint id)
5050{
5051 if (id == 0)
5052 {
5053 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
5054 // returns FALSE
5055 return GL_FALSE;
5056 }
5057
5058 const TransformFeedback *transformFeedback = getTransformFeedback(id);
5059 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
5060}
5061
5062void Context::pauseTransformFeedback()
5063{
5064 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5065 transformFeedback->pause();
5066}
5067
5068void Context::resumeTransformFeedback()
5069{
5070 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
5071 transformFeedback->resume();
5072}
5073
Jamie Madill12e957f2017-08-26 21:42:26 -04005074void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
5075{
5076 const Program *programObject = getProgram(program);
5077 programObject->getUniformuiv(location, params);
5078}
5079
5080GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
5081{
5082 const Program *programObject = getProgram(program);
5083 return programObject->getFragDataLocation(name);
5084}
5085
5086void Context::getUniformIndices(GLuint program,
5087 GLsizei uniformCount,
5088 const GLchar *const *uniformNames,
5089 GLuint *uniformIndices)
5090{
5091 const Program *programObject = getProgram(program);
5092 if (!programObject->isLinked())
5093 {
5094 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5095 {
5096 uniformIndices[uniformId] = GL_INVALID_INDEX;
5097 }
5098 }
5099 else
5100 {
5101 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5102 {
5103 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
5104 }
5105 }
5106}
5107
5108void Context::getActiveUniformsiv(GLuint program,
5109 GLsizei uniformCount,
5110 const GLuint *uniformIndices,
5111 GLenum pname,
5112 GLint *params)
5113{
5114 const Program *programObject = getProgram(program);
5115 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
5116 {
5117 const GLuint index = uniformIndices[uniformId];
5118 params[uniformId] = programObject->getActiveUniformi(index, pname);
5119 }
5120}
5121
5122GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
5123{
5124 const Program *programObject = getProgram(program);
5125 return programObject->getUniformBlockIndex(uniformBlockName);
5126}
5127
5128void Context::getActiveUniformBlockiv(GLuint program,
5129 GLuint uniformBlockIndex,
5130 GLenum pname,
5131 GLint *params)
5132{
5133 const Program *programObject = getProgram(program);
5134 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
5135}
5136
5137void Context::getActiveUniformBlockName(GLuint program,
5138 GLuint uniformBlockIndex,
5139 GLsizei bufSize,
5140 GLsizei *length,
5141 GLchar *uniformBlockName)
5142{
5143 const Program *programObject = getProgram(program);
5144 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
5145}
5146
5147void Context::uniformBlockBinding(GLuint program,
5148 GLuint uniformBlockIndex,
5149 GLuint uniformBlockBinding)
5150{
5151 Program *programObject = getProgram(program);
5152 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
5153}
5154
Jamie Madill7f0c5a42017-08-26 22:43:26 -04005155GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
5156{
5157 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
5158 GLsync fenceSync = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
5159
5160 FenceSync *fenceSyncObject = getFenceSync(fenceSync);
5161 Error error = fenceSyncObject->set(condition, flags);
5162 if (error.isError())
5163 {
5164 deleteSync(fenceSync);
5165 handleError(error);
5166 return nullptr;
5167 }
5168
5169 return fenceSync;
5170}
5171
5172GLboolean Context::isSync(GLsync sync)
5173{
5174 return (getFenceSync(sync) != nullptr);
5175}
5176
5177GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5178{
5179 FenceSync *syncObject = getFenceSync(sync);
5180
5181 GLenum result = GL_WAIT_FAILED;
5182 handleError(syncObject->clientWait(flags, timeout, &result));
5183 return result;
5184}
5185
5186void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
5187{
5188 FenceSync *syncObject = getFenceSync(sync);
5189 handleError(syncObject->serverWait(flags, timeout));
5190}
5191
5192void Context::getInteger64v(GLenum pname, GLint64 *params)
5193{
5194 GLenum nativeType = GL_NONE;
5195 unsigned int numParams = 0;
5196 getQueryParameterInfo(pname, &nativeType, &numParams);
5197
5198 if (nativeType == GL_INT_64_ANGLEX)
5199 {
5200 getInteger64vImpl(pname, params);
5201 }
5202 else
5203 {
5204 CastStateValues(this, nativeType, pname, numParams, params);
5205 }
5206}
5207
Jamie Madill3ef140a2017-08-26 23:11:21 -04005208void Context::getBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
5209{
5210 Buffer *buffer = mGLState.getTargetBuffer(target);
5211 QueryBufferParameteri64v(buffer, pname, params);
5212}
5213
5214void Context::genSamplers(GLsizei count, GLuint *samplers)
5215{
5216 for (int i = 0; i < count; i++)
5217 {
5218 samplers[i] = mState.mSamplers->createSampler();
5219 }
5220}
5221
5222void Context::deleteSamplers(GLsizei count, const GLuint *samplers)
5223{
5224 for (int i = 0; i < count; i++)
5225 {
5226 GLuint sampler = samplers[i];
5227
5228 if (mState.mSamplers->getSampler(sampler))
5229 {
5230 detachSampler(sampler);
5231 }
5232
5233 mState.mSamplers->deleteObject(this, sampler);
5234 }
5235}
5236
5237void Context::getInternalformativ(GLenum target,
5238 GLenum internalformat,
5239 GLenum pname,
5240 GLsizei bufSize,
5241 GLint *params)
5242{
5243 const TextureCaps &formatCaps = mTextureCaps.get(internalformat);
5244 QueryInternalFormativ(formatCaps, pname, bufSize, params);
5245}
5246
Jamie Madillc29968b2016-01-20 11:17:23 -05005247} // namespace gl